Skip to content

Instantly share code, notes, and snippets.

@pleasetrythisathome
Last active August 29, 2015 14:06
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 pleasetrythisathome/4f03ba9f729300beea40 to your computer and use it in GitHub Desktop.
Save pleasetrythisathome/4f03ba9f729300beea40 to your computer and use it in GitHub Desktop.
play, pause, kill a go-loop
(defn control-loop
"calls f on each value read from read-chan
returns a control channel that can :play, :pause, and :kill the read loop"
([f read-chan] (control-loop f read-chan (chan)))
([f read-chan control]
(go-loop [action :play]
(let [[v c] (alts! (condp = action
:play [read-chan control]
:pause [control]))]
(when-not (nil? v)
(condp = c
control (when-not (= :kill v)
(recur v))
read-chan (do
(f v)
(recur action))))))
control))
;; our input chan
(def input (chan))
;; pprint all the values in input and hold onto the returned control chan
(def control (control-loop pprint input))
;; will print 0-9
(onto-chan input (range 10) false)
;; pause the loop
(put! control :pause)
;; will do nothing
(onto-chan input (range 10) false)
;; will print 0-9 that was waiting on the channel
(put! control :play)
;; the following three methods all kill the loop
(put! control :kill)
(close! control)
(close! input)
;; will do nothing
(onto-chan input (range 10) false)
;; if you pass a channel with a sliding buffer, when you pause,
;; values put onto the channel will be discarded.
(def input (chan (sliding-buffer 2)))
(def control (control-loop pprint input))
;; will print
(put! input 1)
(put! input 1)
(put! input 1)
;; pause the loop
(put! control :pause)
;; will do nothing
(onto-chan input (range 10) false)
;; will print 8,9 that was waiting on the channel
(put! control :play)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment