;; 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. ;; ;; https://github.com/ztellman/lamina ;; ;; I should also mention, that this is not a simple copy of syntax/semantic notations ;; from Go, I tried to create "clojure-like" variant of how to do the same things (with ;; functional approach of data transformation from initial to desired state). ;; (3) Select ;; Clojure doesn't have "select" (mostly cause of functional approach), ;; but we can simulate it using map* and case calls (let [joe (boring "Joe") ;; Will generate messages each 60 ms timer (periodically 60 (fn [] "You're too slow!")) ;; All channels will be joined with this one select (channel)] (doseq [[t ch] [["joe" joe] ["timer" timer]]] ;; Map message to struct [type message] ;; TODO: Check if I can you (named-channel) for this (join (map* (partial conj [t]) ch) select)) ;; Read from channel until it's not closed (in blocking mode) (receive-all select (fn [[name msg]] (println (str msg (case name "joe" " <== Message from Joe" "timer" " <== Timeout"))))))