Skip to content

Instantly share code, notes, and snippets.

@bendlas
Created April 26, 2010 21:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bendlas/379981 to your computer and use it in GitHub Desktop.
Save bendlas/379981 to your computer and use it in GitHub Desktop.
(ns timer
(:import [java.util Timer TimerTask]))
(def the-timer (Timer.))
(defn timer
"Schedules a callback for delayed execution.
Returns a function, that accepts a parameter:
:bump to restart the timer, returning true only if timer was active, hence was extended by that call
:cancel to abort the timer, returning true only if timer was active, hence was canceled b.t.c."
[delay callback]
(let [current (atom 0) ; bump counter, nil is special for a disabled timer
create-task (fn [rev]
(proxy [TimerTask] []
; only run, when this handler is the latest
(run [] (when (compare-and-set! current rev nil)
(callback)))))
ctl (fn [action]
(condp = action
:bump (when-let [in-current @current]
(when (compare-and-set! current in-current (inc in-current))
(.schedule the-timer
(create-task (inc in-current))
(long delay))
true))
:cancel (loop [] (when-let [in-cur @current] ; :cancel
(if (compare-and-set! current in-cur nil)
true (recur))))))]
(ctl :bump)
ctl))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment