clojure.core.async: how to deal with deadlocks:
This file contains 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. |
No comments:
Post a Comment