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



*executor* ^

NONE
(defonce ^:dynamic *executor* nil)
link

get-executor ^

[]
Added 3.0

gets the print executor

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?

pprint ^

[item]
Added 3.0

cenvenience function for pprint

v 3.0
(defn pprint
  ([item]
   (print (pprint-str item))))
link
(print/pprint {:a 1}) => nil?

pprint-str ^

[item]
Added 3.0

convenience function for pprint-str

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}"

print ^

[& items]
Added 3.0

prints using local handler

v 3.0
(defn print
  ([& items]
   (if env/*local*
     (do (apply submit items) nil)
     (apply clojure.core/print items))))
link
(print/print "hello") => nil?

print-handler ^

[_ items]
Added 3.0

handler for local print

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"

println ^

[& items]
Added 3.0

convenience function for println

v 3.0
(defn println
  ([& items]
   (->> (apply clojure.core/println items)
        (clojure.core/with-out-str)
        (print))))
link
(print/println "hello") => nil?

prn ^

[& items]
Added 3.0

convenience function for prn

v 3.0
(defn prn
  ([& items]
   (->> (apply clojure.core/prn items)
        (clojure.core/with-out-str)
        (print))))
link
(print/prn "hello") => nil?

submit ^

[& entries]
Added 3.0

submits an entry for printing

v 3.0
(defn submit
  ([& entries]
   (apply (:submit (get-executor)) entries)))
link
(print/submit "hello") => nil?