   ; REVIEW
   ; for some reason if heartbeats are started first things work otherwise not
   ;----------------------------------------------------------------------
-  (run-heartbeats publish-chan (conf/heartbeats-interval-ms))
-  
-  (util/start-thread "dead-agent-checker" #(run-dead-agent-check (conf/heartbeats-dead-after-ms)))
+  (let [hb-ms (conf/heartbeats-interval-ms)
+        dead-after-ms (conf/heartbeats-dead-after-ms)]
+    (util/periodically "heartbeats" hb-ms #(publish msg/broadcast-topic {:msg :heartbeat}))
+    (util/periodically "dead-agent-checker" dead-after-ms (partial run-dead-agent-check dead-after-ms)))
 
   (log/info "Populating cache.")
   (populate-cache)

  (log/info "Initializing Quartz.")
  (quartz/init quartz-chan)
  ; quartz puts stuff on the quartz-chan when a trigger is fired
  (run-quartz-processing quartz-chan)


  (log/info "Populating Quartz.")

   If agent doesn't know anything, timeout will have to kick in and fail the job.
   Email users about agent disconnect and affected exec-vertex ids"
  [interval-ms]
  (let [ts-threshold (- (util/now) interval-ms)
        agent-job-map (track/dead-agents-job-map @tracker ts-threshold)
        dead-agents (keys agent-job-map)
        vertex-ids (reduce into #{} (vals agent-job-map))]

    (when (-> vertex-ids empty? not)
      (log/info "Dead agent check, dead agents:" dead-agents ", affected vertex-ids:" vertex-ids)

      ; mark status as unknown in db
      (db/update-execution-vertices-status vertex-ids data/unknown-status (util/now))

      ; remove from tracker
      (swap! tracker track/rm-agents dead-agents)

      (notify/dead-agents dead-agents vertex-ids))))



;-----------------------------------------------------------------------
