Skip to content

Instantly share code, notes, and snippets.

@quux00
Created January 4, 2013 03:23
Show Gist options
  • Save quux00/4449661 to your computer and use it in GitHub Desktop.
Save quux00/4449661 to your computer and use it in GitHub Desktop.
Initial simple implementation of Go "select" or Rack "sync" in Clojure
(defn- choose [ready-chans]
(.take (nth ready-chans (rand-int (count ready-chans)))))
(defn- peek-channels [channels]
(let [ready (doall (keep #(when-not (nil? (.peek %)) %) channels))]
(if (seq ready)
(nth ready (rand-int (count ready))) ;; pick at random if >1 ready
(Thread/sleep 0 500))))
(defn- probe-til-ready [channels]
(loop [chans channels ready-chan nil]
(if ready-chan
(.take ready-chan)
(recur channels (peek-channels channels)))))
(defn select [& channels]
(let [ready (doall (filterv #(not (nil? (.peek %))) channels))]
(if (seq ready)
(choose ready)
(probe-til-ready channels))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment