Skip to content

Instantly share code, notes, and snippets.

@christianromney
Created July 20, 2013 13:42
Show Gist options
  • Save christianromney/6045059 to your computer and use it in GitHub Desktop.
Save christianromney/6045059 to your computer and use it in GitHub Desktop.
(ns async.core
(:require [clojure.core.async :as async :refer :all]
[clojure.core.async.lab :as lab]
[clojure.data.generators :as gen])
(:gen-class))
;; A Message carries some text to be communicated
;; and a wake channel which notifies the originator
;; that it may transmit again.
(defrecord Message [text wake])
;; Trivial macro that executes its body in an
;; infinite loop.
(defmacro forever [& body]
`(while true
~@body))
(defn- snooze
"Takes a nap of a (short) random duration"
[]
(Thread/sleep (int (* 500 (rand)))))
(defn boring
"Print some pseudo-random noise on a channel"
[talk]
(let [wake (chan)
noise #(str % ": " (gen/string "*" (inc (rand-int 15))))]
(go
(doseq [n (iterate inc 1)]
(>! talk (->Message (noise n) wake))
(snooze)
(<! wake)))
talk))
(defn fan-in
"Allow whoever is ready to speak up"
[& in-channels]
(let [merged (chan)]
(go
(forever
(let [[result _] (alts! in-channels)]
(>! merged result))))
merged))
(defn -main
"Experiment with core/async channels"
[& args]
(let [data (fan-in (boring (chan))
(boring (chan)))]
(dotimes [n 5]
(let [msg1 (<!! data)
msg2 (<!! data)]
(println (:text msg1))
(println (:text msg2))
(>!! (:wake msg1) true)
(>!! (:wake msg2) true))))
(println "\nYou're both boring, I'm leaving."))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment