Skip to content

Instantly share code, notes, and snippets.

@quux00
Last active December 10, 2015 11:58
Show Gist options
  • Save quux00/4430718 to your computer and use it in GitHub Desktop.
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.
(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