std.concurrent.print
serialized asynchronous printing for concurrent code
Route print operations through a single batched executor so output from concurrent tasks remains ordered and readable.
1 Overview
std.concurrent.print provides drop-in print, println, prn, and pprint functions. In local execution mode they enqueue output through a shared atom executor; outside that mode they fall back to Clojure's standard printing functions.
2 Walkthrough
2.1 Use concurrent printing
(require '[std.concurrent.print :as concurrent-print])
(future (concurrent-print/println "worker-a" 1))
(future (concurrent-print/println "worker-b" 2))
(concurrent-print/pprint {:status :running :workers 2})
2.2 Submit raw fragments
submit accepts one or more fragments and places them directly onto the print queue. get-executor returns the shared resource and restarts it if its executor has stopped.
(concurrent-print/submit "progress " 50 "%\n")
(keys (concurrent-print/get-executor))
(concurrent-print/pprint-str {:a 1 :b 2})
3 API
v 3.0
(defn get-executor
[]
(let [exe (or *executor*
(res/res :hara/print))]
(if (or (nil? exe)
(exe/exec:shutdown? (:executor exe)))
(res/res:restart :hara/print)
exe)))
link
(print/get-executor) => map?
v 3.0
(defn pprint-str
([item]
(let [s (clojure.core/with-out-str
(pprint/pprint item))]
(subs s 0 (dec (count s))))))
link
(print/pprint-str {:a 1}) => "{:a 1}"
v 3.0
(defn print
([& items]
(if env/*local*
(do (apply submit items) nil)
(apply clojure.core/print items))))
link
(print/print "hello") => nil?
v 3.0
(defn print-handler
([_ items]
(doseq [item items]
(clojure.core/print item))
(flush)))
link
(with-out-str (print/print-handler nil ["hello" " " "world"])) => "hello world"
v 3.0
(defn println
([& items]
(->> (apply clojure.core/println items)
(clojure.core/with-out-str)
(print))))
link
(print/println "hello") => nil?