 (defn do-health-checks
   "Takes a map from service -> service instances and performs health checks in parallel. Returns a map of service -> service instances."
   [service->service-instances available? service-id->service-description-fn]
-  (let [service->service-instance-futures (start-health-checks service->service-instances available? service-id->service-description-fn)]
-    (loop [[[service {:keys [active-instances] :as instances}] & rest] (seq service->service-instance-futures)
-           service->service-instances' {}]
-      (if-not service
-        service->service-instances'
-        (let [active-instances (doall (map async/<!! active-instances))]
-          (recur rest (assoc service->service-instances'
-                        service
-                        (assoc instances :active-instances active-instances))))))))
+  (let [timeout-threshold-mins 2
+        timeout-channel (async/timeout (-> timeout-threshold-mins t/minutes t/in-millis))
+        slowness-monitor-promise (promise)]
+    (async/go
+      (async/<! timeout-channel)
+      (when (not (realized? slowness-monitor-promise))
+        (log/warn "scheduler-syncer: health checks are taking longer than" timeout-threshold-mins "minute(s) to complete")))
+    (let [service->service-instance-futures (start-health-checks service->service-instances available? service-id->service-description-fn)]
+      (loop [[[service {:keys [active-instances] :as instances}] & rest] (seq service->service-instance-futures)
+             service->service-instances' {}]
+        (if-not service
+          (do
+            (deliver slowness-monitor-promise :done)
+            (async/close! timeout-channel)
+            service->service-instances')
+          (let [active-instances (doall (map async/<!! active-instances))]
+            (recur rest (assoc service->service-instances'
+                          service
+                          (assoc instances :active-instances active-instances)))))))))
 
 (defn- update-scheduler-state
   "Queries marathon, sends data on app and instance statuses to router state maintainer, and returns scheduler state"

                       :priority true)]
            (recur next-state)))
        (catch Exception e
          (log/error e "Fatal error in service-chan-maintainer")
          (System/exit 1))))
    {:exit-chan exit-chan
     :query-chan state-query-chan}))

(ns waiter.scheduler
  (:require [clj-time.core :as t]
            [clojure.core.async :as async]
            [clojure.string :as str]
            [clojure.tools.logging :as log]
            [metrics.timers :as timers]
