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!
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].)
Related
Here's a simple re-frame app that I tried to create based on the existing example project in re-frame's github repo. But it is only displaying things from the html file. Seems like no event is being dispatched. Can anyone point out what am I doing wrong? Thanks.
(ns simple.core
(:require [reagent.core :as reagent]
[re-frame.core :as rf]
[clojure.string :as str]))
(rf/reg-event-db
:rand
(fn [db [_ _]]
(assoc db :winner ( + 2 (rand-int 3)))))
(rf/reg-sub
:winner
(fn [db _]
(:winner db)))
(def participants ["Alice" "Bob" "Ellie"])
(defn winners-name
[idx]
(get participants idx))
(defn show-winner
[]
[:h1
(winners-name
(#(rf/subscribe [:winner])))])
(defn ui
[]
[:div
[:h1 "Lottery"]
[show-winner]])
(defn ^:export run
[]
(rf/dispatch-sync [:rand])
(reagent/render [ui]
(js/document.getElementById "app")))
The :rand handler will produce nil most times since you are adding 2 to the generated value and the participants vector only has 3 entries.
The issue is caused because of a pair of extra parenthesis around the deref thing. So the function winners-name is treating it as a list instead of an integer.
(winners-name
(#(rf/subscribe [:winner]))
I'm trying to make a sleep function in ClojureScript (w/ Reagent):
(ns cljweb.webpage
(:require [reagent.core :as reagent]))
(def temp-atom (reagent/atom 0))
(defn sleep [msec]
(js/setTimeout (fn []) msec))
(defn page []
[:div
[:p #temp-atom]
[:button
{:on-click
(fn []
(sleep 3000)
(swap! temp-atom inc))}
"Click me!"]])
For some reason, this doesn't sleep properly - when I click the "Click me!" button, temp-atom increments instantly - when I time it, by putting this after in page:
[:p (time (sleep 3000))]
I get this in the console:
"Elapsed time: 0.015000 msecs"
What did I do wrong in the code?
Javascript's setTimeout function accepts two arguments: function and timeout in milliseconds. Its contract is to run the received function after the timeout passes.
Your code doesn't pass the function you would like to execute after 3 seconds but instead passes a no-op function ((fn [])).
Your sleep function should look like this (and it would be better named timeout or you could just call js/setTimeout directly in your on-click handler):
(defn sleep [f ms]
(js/setTimeout f ms))
You also need to change how you call this function:
(sleep #(swap! temp-atom inc) 3000)
Or with calling js/setTimeout directly:
(js/setTimeout #(swap! temp-atom inc) 3000)
With ClojureScript, the best way to write asynchronous code is with the CoreAsync library. In your case, take a look at the timeout function:
(ns cljweb.webpage
(:use-macros [cljs.core.async.macros :only [go]]
(:require [reagent.core :as reagent]
[cljs.core.async :refer [<! timeout]]))
(def temp-atom (reagent/atom 0))
(defn page []
[:div
[:p #temp-atom]
[:button
{:on-click
(fn []
(go
(<! (timeout 3000))
(swap! temp-atom inc)))}
"Click me!"]])
There is a way to implement such functionality using goog.async.Debouncer
Here is an example:
(ns example.utils
(:require [goog.async.Debouncer]))
(defn debounce [f interval]
(let [dbnc (goog.async.Debouncer. f interval)]
(fn [& args] (.apply (.-fire dbnc) dbnc (to-array args)))))
(defn save-input! [input]
(js/console.log "Saving input" input))
(def save-input-debounced!
(debounce save-input! 3000))
(save-input-debounced! "hi")
This is a snippet from the Reagent project. Looking at complete-all and clear-done, I understand the point is to swap out the modified map. I don't understand how it's being done. The definition of mmap calls for 3 parameters — and complete-all seems to be calling it with two, namely map and #(assoc-in % [1 :done] v). clear-done calls with remove and #(get-in % [1 :done]). I tried using the repl to experiment but couldn't get the requires to work out.
(ns todomvc.core
(:require [reagent.core :as r]))
(defonce todos (r/atom (sorted-map)))
(defonce counter (r/atom 0))
(defn add-todo [text]
(let [id (swap! counter inc)]
(swap! todos assoc id {:id id :title text :done false})))
(defn toggle [id] (swap! todos update-in [id :done] not))
(defn save [id title] (swap! todos assoc-in [id :title] title))
(defn delete [id] (swap! todos dissoc id))
(defn mmap [m f a] (->> m (f a) (into (empty m))))
(defn complete-all [v] (swap! todos mmap map #(assoc-in % [1 :done] v)))
(defn clear-done [] (swap! todos mmap remove #(get-in % [1 :done])))
The existing map is passed as the first argument to the function. When all else fails...
What's best way in clojure to implement something like an actor or agent (asynchronously updated, uncoordinated reference) that does the following?
gets sent messages/data
executes some function on that data to obtain new state; something like (fn [state new-msgs] ...)
continues to receive messages/data during that update
once done with that update, runs the same update function against all messages that have been sent in the interim
An agent doesn't seem quite right here. One must simultaneously send function and data to agents, which doesn't leave room for a function which operates on all data that has come in during the last update. The goal implicitly requires a decoupling of function and data.
The actor model seems generally better suited in that there is a decoupling of function and data. However, all actor frameworks I'm aware of seem to assume each message sent will be processed separately. It's not clear how one would turn this on it's head without adding extra machinery. I know Pulsar's actors accept a :lifecycle-handle function which can be used to make actors do "special tricks" but there isn't a lot of documentation around this so it's unclear whether the functionality would be helpful.
I do have a solution to this problem using agents, core.async channels, and watch functions, but it's a bit messy, and I'm hoping there is a better solution. I'll post it as a solution in case others find it helpful, but I'd like to see what other's come up with.
Here's the solution I came up with using agents, core.async channels, and watch functions. Again, it's a bit messy, but it does what I need it to for now. Here it is, in broad strokes:
(require '[clojure.core.async :as async :refer [>!! <!! >! <! chan go]])
; We'll call this thing a queued-agent
(defprotocol IQueuedAgent
(enqueue [this message])
(ping [this]))
(defrecord QueuedAgent [agent queue]
IQueuedAgent
(enqueue [_ message]
(go (>! queue message)))
(ping [_]
(send agent identity)))
; Need a function for draining a core async channel of all messages
(defn drain! [c]
(let [cc (chan 1)]
(go (>! cc ::queue-empty))
(letfn
; This fn does all the hard work, but closes over cc to avoid reconstruction
[(drainer! [c]
(let [[v _] (<!! (go (async/alts! [c cc] :priority true)))]
(if (= v ::queue-empty)
(lazy-seq [])
(lazy-seq (cons v (drainer! c))))))]
(drainer! c))))
; Constructor function
(defn queued-agent [& {:keys [buffer update-fn init-fn error-handler-builder] :or {:buffer 100}}]
(let [q (chan buffer)
a (agent (if init-fn (init-fn) {}))
error-handler-fn (error-handler-builder q a)]
; Set up the queue, and watcher which runs the update function when there is new data
(add-watch
a
:update-conv
(fn [k r o n]
(let [queued (drain! q)]
(when-not (empty? queued)
(send a update-fn queued error-handler-fn)))))
(QueuedAgent. a q)))
; Now we can use these like this
(def a (queued-agent
:init-fn (fn [] {:some "initial value"})
:update-fn (fn [a queued-data error-handler-fn]
(println "Receiving data" queued-data)
; Simulate some work/load on data
(Thread/sleep 2000)
(println "Done with work; ready to queue more up!"))
; This is a little warty at the moment, but closing over the queue and agent lets you requeue work on
; failure so you can try again.
:error-handler-builder
(fn [q a] (println "do something with errors"))))
(defn -main []
(doseq [i (range 10)]
(enqueue a (str "data" i))
(Thread/sleep 500) ; simulate things happening
; This part stinks... have to manually let the queued agent know that we've queued some things up for it
(ping a)))
As you'll notice, having to ping the queued-agent here every time new data is added is pretty warty. It definitely feels like things are being twisted out of typical usage.
Agents are the inverse of what you want here - they are a value that gets sent updating functions. This easiest with a queue and a Thread. For convenience I am using future to construct the thread.
user> (def q (java.util.concurrent.LinkedBlockingDeque.))
#'user/q
user> (defn accumulate
[summary input]
(let [{vowels true consonents false}
(group-by #(contains? (set "aeiouAEIOU") %) input)]
(-> summary
(update-in [:vowels] + (count vowels))
(update-in [:consonents] + (count consonents)))))
#'user/accumulate
user> (def worker
(future (loop [summary {:vowels 0 :consonents 0} in-string (.take q)]
(if (not in-string)
summary
(recur (accumulate summary in-string)
(.take q))))))
#'user/worker
user> (.add q "hello")
true
user> (.add q "goodbye")
true
user> (.add q false)
true
user> #worker
{:vowels 5, :consonents 7}
I came up with something closer to an actor, inspired by Tim Baldridge's cast on actors (Episode 16). I think this addresses the problem much more cleanly.
(defmacro take-all! [c]
`(loop [acc# []]
(let [[v# ~c] (alts! [~c] :default nil)]
(if (not= ~c :default)
(recur (conj acc# v#))
acc#))))
(defn eager-actor [f]
(let [msgbox (chan 1024)]
(go (loop [f f]
(let [first-msg (<! msgbox) ; do this so we park efficiently, and only
; run when there are actually messages
msgs (take-all! msgbox)
msgs (concat [first-msg] msgs)]
(recur (f msgs)))))
msgbox))
(let [a (eager-actor (fn f [ms]
(Thread/sleep 1000) ; simulate work
(println "doing something with" ms)
f))]
(doseq [i (range 20)]
(Thread/sleep 300)
(put! a i)))
;; =>
;; doing something with (0)
;; doing something with (1 2 3)
;; doing something with (4 5 6)
;; doing something with (7 8 9 10)
;; doing something with (11 12 13)
I have a situation where I am creating and destroying objects in one clojure namespace, and want another namespace to co-ordinate. However I do not want the first namespace to have to call the second explicitly on object destruction.
In Java, I could use a listener. Unfortunately the underlying java libraries do not signal events on object destruction. If I were in Emacs-Lisp, then I'd use hooks which do the trick.
Now, in clojure I am not so sure. I have found the Robert Hooke library https://github.com/technomancy/robert-hooke. But this is more like defadvice in elisp terms -- I am composing functions. More over the documentation says:
"Hooks are meant to extend functions you don't control; if you own the target function there are obviously better ways to change its behaviour."
Sadly, I am not finding it so obvious.
Another possibility would be to use add-watch, but this is marked as alpha.
Am I missing another obvious solution?
Example Added:
So First namespace....
(ns scratch-clj.first
(:require [scratch-clj.another]))
(def listf (ref ()))
(defn add-object []
(dosync
(ref-set listf (conj
#listf (Object.))))
(println listf))
(defn remove-object []
(scratch-clj.another/do-something-useful (first #listf))
(dosync
(ref-set listf (rest #listf)))
(println listf))
(add-object)
(remove-object)
Second namespace
(ns scratch-clj.another)
(defn do-something-useful [object]
(println "object removed is:" object))
The problem here is that scratch-clj.first has to require another and explicitly push removal events across. This is a bit clunky, but also doesn't work if I had "yet-another" namespace, which also wanted to listen.
Hence I thought of hooking the first function.
Is this solution suitable to your requirements?
scratch-clj.first:
(ns scratch-clj.first)
(def listf (atom []))
(def destroy-listeners (atom []))
(def add-listeners (atom []))
(defn add-destroy-listener [f]
(swap! destroy-listeners conj f))
(defn add-add-listener [f]
(swap! add-listeners conj f))
(defn add-object []
(let [o (Object.)]
(doseq [f #add-listeners] (f o))
(swap! listf conj o)
(println #listf)))
(defn remove-object []
(doseq [f #destroy-listeners] (f (first #listf)))
(swap! listf rest)
(println #listf))
Some listeners:
(ns scratch-clj.another
(:require [scratch-clj.first :as fst]))
(defn do-something-useful-on-remove [object]
(println "object removed is:" object))
(defn do-something-useful-on-add [object]
(println "object added is:" object))
Init binds:
(ns scratch-clj.testit
(require [scratch-clj.another :as another]
[scratch-clj.first :as fst]))
(defn add-listeners []
(fst/add-destroy-listener another/do-something-useful-on-remove)
(fst/add-add-listener another/do-something-useful-on-add))
(defn test-it []
(add-listeners)
(fst/add-object)
(fst/remove-object))
test:
(test-it)
=> object added is: #<Object java.lang.Object#c7aaef>
[#<Object java.lang.Object#c7aaef>]
object removed is: #<Object java.lang.Object#c7aaef>
()
It sounds a lot like what you're describing is callbacks.
Something like:
(defn make-object
[destructor-fn]
{:destructor destructor-fn :other-data "data"})
(defn destroy-object
[obj]
((:destructor obj) obj))
; somewhere at the calling code...
user> (defn my-callback [o] (pr [:destroying o]))
#'user/my-callback
user> (destroy-object (make-object my-callback))
[:destroying {:destructor #<user$my_callback user$my_callback#73b8cdd5>, :other-data "data"}]
nil
user>
So, here is my final solution following mobytes suggestion. A bit more work, but
I suspect that I will want this in future.
Thanks for all the help
;; hook system
(defn make-hook []
(atom []))
(defn add-hook [hook func]
(do
(when-not
(some #{func} #hook)
(swap! hook conj func))
#hook))
(defn remove-hook [hook func]
(swap! hook
(partial
remove #{func})))
(defn clear-hook [hook]
(reset! hook []))
(defn run-hook
([hook]
(doseq [func #hook] (func)))
([hook & rest]
(doseq [func #hook] (apply func rest))))
(defn phils-hook []
(println "Phils hook"))
(defn phils-hook2 []
(println "Phils hook2"))
(def test-hook (make-hook))
(add-hook test-hook phils-hook)
(add-hook test-hook phils-hook2)
(run-hook test-hook)
(remove-hook test-hook phils-hook)
(run-hook test-hook)