Skip to content

Instantly share code, notes, and snippets.

@favila
Created September 19, 2013 14:32
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 favila/6624418 to your computer and use it in GitHub Desktop.
Save favila/6624418 to your computer and use it in GitHub Desktop.
parallel-chan-map: Read in-chan and put result of `(apply f in-chan-value args)` on out-chan, running items in "parallel" and yielding results out-of-order. Works with Clojure or Clojurescript.
(ns parallel-chan-map
(:require-macros [cljs.core.async.macros :refer (go alt!)])
(:require [cljs.core.async :refer (>! close! put! chan )]))
(defn parallel-chan-map
"Read in-chan and put result of `(apply f in-chan-value args)` on out-chan,
potentially running items in parallel and yielding results out-of-order.
Function f must return something takeable (e.g. a go-block, channel, promise),
in essence spawning a \"subprocess\" which this function manages as a pool
internally."
[in-chan out-chan f & args]
(go (loop [chans [in-chan]]
(when-not (empty? chans)
(let [[v c] (alts! chans)]
(if (nil? v)
(recur (remove #{c} chans))
(if (identical? c in-chan)
(recur (conj chans (apply f v args)))
(do (>! out-chan v) (recur chans))))))))
out-chan)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment