       (.setUncaughtExceptionHandler uncaught-exception-handler)
       (.build)))
 
-(defn create [task]
-  (assert (fn? task) {:task task})
-  {::available-tasks (doto (ArrayBlockingQueue. 1)
-                       (.add task))
-   ::executor (Executors/newFixedThreadPool 1 thread-factory)})
-
 (defn- run-safely! [task]
   (try
     (task)

;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.poller
  (:require [clojure.tools.logging :as log])
  (:import (com.google.common.util.concurrent ThreadFactoryBuilder)
           (java.lang Thread$UncaughtExceptionHandler)
           (java.util Queue)
           (java.util.concurrent ExecutorService Executors TimeUnit ArrayBlockingQueue)))

(def ^:private uncaught-exception-handler
  (reify Thread$UncaughtExceptionHandler

        (when-let [handler (.getUncaughtExceptionHandler t)]
          (.uncaughtException handler t e))))))

(defrecord AsyncPoller [^Queue available-tasks
                        ^ExecutorService executor]
  Poller
  (trigger! [_]
    (when-let [task (.poll available-tasks)]
      (.execute executor (fn []
                           (.add available-tasks task)
                           (run-safely! task)))))

  (await [_]
    (let [future (.submit executor ^Runnable (fn []))]
      (.get future)))

  (shutdown! [_]
    (doto executor
      (.shutdown)
      (.awaitTermination 1 TimeUnit/MINUTES)
      (.shutdownNow))))

(defn create [task]
  (assert (fn? task) {:task task})
  (AsyncPoller. (doto (ArrayBlockingQueue. 1)
                  (.add task))
                (Executors/newFixedThreadPool 1 thread-factory)))
