Skip to content

Instantly share code, notes, and snippets.

@frankhenderson
Last active January 20, 2019 04:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frankhenderson/d60471e64faec9e2158c to your computer and use it in GitHub Desktop.
Save frankhenderson/d60471e64faec9e2158c to your computer and use it in GitHub Desktop.
learning about channels ... context: ClojureScript, nodejs, spawning a child_process
(ns some-project.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.nodejs :as nodejs]
[cljs.core.async :as a :refer [put! <! chan alts! timeout]]))
(nodejs/enable-util-print!)
(def -main (fn [] nil))
(set! *main-cli-fn* -main)
(def spawn (.-spawn (js/require "child_process")))
(defn exec-chan
"spawns a child process for cmd with args. routes stdout, stderr, and
the exit code to a channel. returns the channel immediately."
[cmd args]
(let [c (chan), p (spawn cmd args)]
(.on (.-stdout p) "data" #(put! c [:out (str %)]))
(.on (.-stderr p) "data" #(put! c [:err (str %)]))
(.on p "close" #(put! c [:exit (str %)]))
c))
(defn exec
"executes cmd with args. returns a channel immediately which
will eventually receive a result vector of pairs [:kind data-str]
with the last pair being [:exit code]"
[cmd & args]
(let [c (exec-chan cmd (clj->js args))]
(go (loop [output (<! c) , result []]
;;(go (loop [output (alts! c (timeout 2)), result []]
(if (= :exit (first output))
(conj result output)
(recur (<! c) (conj result output)))))))
(defn test-fn []
(go (let [result (<! (exec "./test.sh" "-d" "3"))]
;; do something with the result here
(println result))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment