Be Genius

me

Bo Jeanes

I am an software engineer who has lived and worked in New York, Brisbane, Chicago, San Francisco, and now Melbourne. I primarily work in Ruby though am a functional programmer at heart and a fan of programming languages in general. In particular, I love Rust and Clojure but keep my eye on many langauges all the time.

Call Clojure function on a timer

In Clojure, I didn't see a nice way to simply call a function on a timer (e.g. to poll for changes in another service).

I didn't find something in clojure.core to achieve this readily (but clojure.core is quite big, so I may have missed something obvious — let me know), so I whipped up the following to put in my project's util.clj file:

(defn tick
  "Call f with args every ms. First call will be after ms"
  [ms f & args]

  (future
    (doseq [f (repeatedly #(apply f args))]
      (Thread/sleep ms)
      (f))))

(defn tick-now
  "Call f with args every ms. First call will be immediately (and blocking)"
  [ms f & args]

  (apply f args)
  (apply tick ms f args)

There are two variants. tick waits ms milliseconds and then calls f with args and repeats indefinitely. tick-now does the same thing except it calls f with args before starting the timer.

They are simple to use:

user=> (tick 500 #(println "hi"))
; 500ms delay
hi
; 500ms delay
hi
; 500ms delay
hi
...

In my project, I'm using them like so:

(defn start-fetchers
  [api-token]

  (future
    (let [minutes (partial * 60 1000)]
      (tick-now (minutes 60)
                update-project-list!
                api-token)

      (tick-now (minutes 5)
                fetch-milestones!
                api-token
                projects-to-fetch
                milestones-by-project))))

Comments

  1. Aaron Bedra pinged me with this article that shows how to do this by taking advantage of java.util.concurrent.ScheduledThreadPoolExecutor. In retrospect, that's pretty obvious — unfortunately, one doesn't think of these things readily when you haven't done in-depth Java in a long time.

    by Bo Jeanes on
  2. Cool stuff!

    The Overtone project has a rather full-featured set of scheduling functions that have recently been pulled out into a separate library, at-at. Also worth checking out.

    by Scott Parker on

You need to login with GitHub in order to comment.