Skip to content

Instantly share code, notes, and snippets.

@kachayev
Last active October 7, 2015 09:57
Show Gist options
  • Select an option

  • Save kachayev/3146759 to your computer and use it in GitHub Desktop.

Select an option

Save kachayev/3146759 to your computer and use it in GitHub Desktop.
Channels-driven concurrency with Clojure
;; Channels-driven concurrency with Clojure
;; Clojure variant for code examples from this gist:
;; https://gist.github.com/3124594
;; Primarily taken from Rob Pike's talk on Google I/O 2012:
;; http://www.youtube.com/watch?v=f6kdp27TYZs&feature=youtu.be
;;
;; Concurrency is the key to designing high performance network services.
;; Clojure provides several concurrency primitives, like futures/promises, atom, agent etc.
;; There is no implementation for "Go channels" in core, but we can use
;; 3rd-party library Lamina to do the same things.
;; (1) Generator: function that returns the channel
(use 'lamina.core)
(defn boring
[name]
(let [ch (channel)]
;; future will run separately from main control flow
(future
(let [after (int (rand 500))]
(Thread/sleep after)
(enqueue ch (str name ": I'm boring after " after)))
;; return the channel to caller
ch))
;; With single instance
(let [joe (boring "Joe")] (dotimes [_ 5] (receive joe println)))
(println "You're boring: I'm leaving.")
;; More instances...
(let [joe (boring "Joe") ann (boring "Ann")]
(dotimes [_ 10] (apply #(receive % println) [joe ann])))
(println "You're boring: I'm leaving.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment