Replace brittle timeout with a background heartbeat thread

@thieman 


Should probably be a daemon thread