Last active
December 10, 2015 11:58
-
-
Save quux00/4430718 to your computer and use it in GitHub Desktop.
Part of the go-lightly utility namespace showing the go and go& macros.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns thornydev.go-lightly | |
(:refer-clojure :exclude [peek take]) | |
(:import (java.io Closeable) | |
(java.util ArrayList) | |
(java.util.concurrent LinkedTransferQueue TimeUnit | |
LinkedBlockingQueue TimeoutException))) | |
;; ---[ go routines ]--- ;; | |
(def inventory (atom [])) | |
(defmacro go | |
"Launches a Clojure future as a 'go-routine' and returns the future. | |
It is not necessary to keep a reference to this future, however. | |
Instead, you can call the accompanying stop function to | |
shutdown (cancel) all futures created by this function." | |
[& body] | |
`(let [fut# (future ~@body)] | |
(swap! inventory conj fut#) | |
fut#)) | |
(defn stop | |
"Stop (cancel) all futures started via the go macro. | |
This should only be called when you are finished with | |
all go routines running in your app, ideally at the end | |
of the program. It can be reused on a new set of go | |
routines, as long as they were started after this stop | |
fn returned, as it clears an cached of remembered go | |
routines that could be subject to a race condition." | |
[] | |
(doseq [f @inventory] (future-cancel f)) | |
(reset! inventory []) | |
nil) | |
(defn shutdown | |
"Stop (cancel) all futures started via the go macro and | |
then call shutdown-agents to close down the entire Clojure | |
agent/future thread pool." | |
[] | |
(stop) | |
(shutdown-agents)) | |
(defmacro go& | |
"Launch a 'go-routine' like deamon Thread to execute the body. | |
This macro does not yield a future so it cannot be dereferenced. | |
Instead it returns the Java Thread itself. | |
It is intended to be used with channels for communication | |
between threads. This thread is not part of a managed Thread | |
pool so cannot be directly shutdown. It will stop either when | |
all non-daemon threads cease or when you stop it some ad-hoc way." | |
[& body] | |
`(doto (Thread. (fn [] (do ~@body))) (.setDaemon true) (.start))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment