(ns scheduled-agent (:import java.util.concurrent.Executors java.util.concurrent.TimeUnit) (:use clojure.stacktrace)) (defn- runnable-proxy [f] (proxy [Runnable] [] (run [] (f)))) (defn scheduled-agent [func period init] (let [pool (Executors/newScheduledThreadPool 1) data (ref init) pfunc (runnable-proxy (fn [] (try (dosync (ref-set data (func (ensure data)))) (catch Exception e (print-stack-trace e 5))))) future (.scheduleWithFixedDelay pool pfunc 0 period TimeUnit/SECONDS)] {:pool pool :data data :future future :func func :period period :init init})) (defn poll [{d :data}] "Return current contents of agent." @d) (defn cancel! [{f :future}] "Cancel automatic updating of agent data. Cannot be restarted." (.cancel f false)) (defn update! [{func :func data :data}] "Synchronously update contents of agent." (dosync (ref-set data (func (ensure data)))))