leontalbot
leontalbot

Reputation: 2543

Using clojure schedulers

How to evaluate a function correctly every minute using at-at and chime?

Here are my tests:

(require '[overtone.at-at :refer :all]
         '[chime :refer [chime-at]]
         '[clj-time.periodic :refer [periodic-seq]]
         '[clj-time.core :as t])

;; 1. Use of future

(defonce data1 (atom {:num 1}))

(defonce updater
  (future
    (while true
      (swap! data1 update-in [:num] inc)
      (Thread/sleep 60000))))


;; 2. Using at-at

(defonce data2 (atom {:num 1}))

(def my-pool (mk-pool))

(every 60000 #(swap! data2 update-in [:num] inc) my-pool)


;; 3. Using chime

(defonce data3 (atom {:num 1}))

(chime-at (periodic-seq (t/now) (-> 60 t/seconds))
          (fn [] (swap! data3 update-in [:num] inc))
          {:error-handler (fn [e] (str e))})

After 5 minutes:

@data1
;;=> {:num 5}
@data2
;;=> {:num 8}
@data3
;;=> {:num 1}

Why is at-at counting to fast? Why is chimenot counting at all?

Thank you!

Upvotes: 1

Views: 467

Answers (1)

Michał Marczyk
Michał Marczyk

Reputation: 84331

Not sure what's up with at-at.

As for Chime, chime-at calls the callback function with the time of the current chime, so you'll need to amend your callback to something like

(fn [time] (swap! data3 update-in [:num] inc))

With (fn [] …) you'll get an ArityException at each chime and your :error-handler swallows those. (Chime's default handler prints a stack trace; NB. depending on your setup that stack trace may or may not be visible in your REPL window – for example with a fairly typical Emacs/CIDER setup you might have to switch to an *nrepl-server* buffer to see it.)

(Incidentally, in 1.7 alphas you can use update :num instead of update-in [:num].)

Upvotes: 2

Related Questions