Last active
November 7, 2018 12:30
-
-
Save lnostdal/3409086d436359888ade175311fe0a55 to your computer and use it in GitHub Desktop.
clojure.core.async: how to deal with deadlocks
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
| ;;; https://www.Quanto.ga | |
| ;; clojure.core.async: how to deal with deadlocks | |
| ;; | |
| ;; If you have a channel that in the "reader" or consumer also sends | |
| ;; to itself you might end up with a deadlock in certain cases. Especially | |
| ;; if you don't want to use buffered channels -- perhaps because it is | |
| ;; impossible to predict how much of a buffer you will need: | |
| (let [ch (async/chan) | |
| f (future | |
| (dotimes [i 3] | |
| (println "ch:" (async/<!! ch)) | |
| (async/>!! ch i)) | |
| (println "ch (last one): " (async/<!! ch)))] | |
| (try | |
| (async/>!! ch -1) | |
| (Thread/sleep 500) | |
| (finally | |
| (future-cancel f))) | |
| (println "...done")) | |
| ;; ch: -1 | |
| ;; ...done | |
| ;; By using async/go or async/thread you can deal with this: | |
| (let [ch (async/chan) | |
| f (future | |
| (dotimes [i 3] | |
| (println "ch:" (async/<!! ch)) | |
| (async/go (async/>! ch i))) ;; or (async/thread (async/>!! ch i)) | |
| (println "ch (last one): " (async/<!! ch)))] | |
| (try | |
| (async/>!! ch -1) | |
| (Thread/sleep 500) | |
| (finally | |
| (future-cancel f))) | |
| (println "...done")) | |
| ;; ch: -1 | |
| ;; ch: 0 | |
| ;;ch: 1 | |
| ;; ch (last one): 2 | |
| ;;...done | |
| ;; Of course one could also use buffering in this case, | |
| ;; but this changes the properties of your system in a different way. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment