Implementing a clojure-only periodic timer...

644 views
Skip to first unread message

Bill Caputo

unread,
Dec 1, 2011, 12:17:40 PM12/1/11
to clo...@googlegroups.com
Hi All,

I am currently considering an approach similar to the following for
periodically sending an update to an agent and I'm looking for
feedback on whether there is anything wrong with it, whether it's
idiomatic clojure (sorry I'm in the pro-that-term camp) and whether
there are other pure-clojure alternatives I should consider (I also
realize there are java-based periodic timers I could use as well):

(def *timer* (agent nil)) ; perhaps an atom instead?
(defn start-timer [ms a f]
(letfn [(tfn [m] (future (do (Thread/sleep ms) (send a f) (send
*timer* tfn))))]
(send *timer* tfn)))

given an agent:
(def data (agent 0))

we could kick off an update every 3 seconds thusly:
(start-timer 3000 data #(inc %))

A real implementation would likely have to address further
considerations like stopping/cancelling the timer, not using a global
for the timer, and what happens if start-timer is called twice, but
this is the basic idea I'm considering...

feedback welcome,

thanks,
bill

gaz jones

unread,
Dec 1, 2011, 12:45:00 PM12/1/11
to clo...@googlegroups.com
Hey Bill, I would have thought you would have to have a pretty good
reason for not using an executor for this?

(let [executor (Executors/newSingleThreadScheduledExecutor)]
(.scheduleAtFixedRate executor your-func 0 3 TimeUnit/SECONDS))

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

Bill Caputo

unread,
Dec 1, 2011, 1:02:53 PM12/1/11
to clo...@googlegroups.com
On Dec 1, 2011, at 11:45 AM, gaz jones wrote:

>Hey Bill, I would have thought you would have to have a pretty good
>reason for not using an executor for this?

Just that I really never spent much time as a Java programmer, so
evaluating the merits/tradeoffs/gotchas of using native (and 3rd
party) Java libs from clojure is another level of complexity that I've
been avoiding unless a clojure-only approach/library is deficient in
some way. IOW - my heuristic has been to try for a clojure-only
solution before looking at Java because that's a pretty big ocean of
stuff to comb through...

That said, I'm not *opposed* to using Java directly either - and it
sounds like using an Executor might be an example of the "if Java
ain't broke, don't fix it" approach that clojure takes and thus more
or less idiomatic, so I'm fine with going that route if that's the
case.

In short: thanks for the answer gaz...


bill

Stuart Sierra

unread,
Dec 1, 2011, 5:12:23 PM12/1/11
to clo...@googlegroups.com
ScheduledThreadPoolExecutor is the way to go. But you can do it in "pure" Clojure with Agents, send-off, and Thread/sleep.

-S

Benny Tsai

unread,
Dec 2, 2011, 12:02:04 AM12/2/11
to clo...@googlegroups.com
Overtone's 'at-at' library is a thin Clojure wrapper over ScheduledThreadPoolExecutor with a nice interface.  I think you should be able to build a timer on top of it pretty easily.

https://github.com/overtone/at-at

Bill Caputo

unread,
Dec 2, 2011, 10:58:26 AM12/2/11
to clo...@googlegroups.com

On Dec 1, 2011, at 11:02 PM, Benny Tsai wrote:

> Overtone's 'at-at' library is a thin Clojure wrapper over ScheduledThreadPoolExecutor with a nice interface. I think you should be able to build a timer on top of it pretty easily.
>
> https://github.com/overtone/at-at

Thanks Benny; I went with the approach that gaz suggested as it's exactly what I needed -- however any excuse to play with anything related to overtone is +1 :-)

bill

Reply all
Reply to author
Forward
0 new messages