• Clojure
  • 42 lines
  • 89 views
  • 4 forks
  • Pasted by anonymous on October 28, 2013
;; code to be evaluated at the repl to reproduce possible async bug
;; that makes go related operations block forever after 50 parallel
;; blocking takes have been invoked in loops in go-blocks

(use '[clojure.core.async :only [>! <! >!! <!! chan go thread]])

(defn go-works?
  []
  (let [test-ch (chan)
        r (promise)]
    (go (deliver r (<! test-ch)))
    (>!! test-ch true)
    @r))

(defn break-async
  []
  (dotimes [_ 50]
    (go
     (loop [_ (<!! (chan))] ;; the blocking take must happen in a loop
                            ;; binding or recur inside of a go-block
       ))))

(defn count-while-works
  []
  (let [c (atom 0)]
    (thread ;; executing in another thread makes no difference
     (loop [cnt (swap! c inc)]
       (go (loop [_ (<!! (chan))]))
       (go-works?)
       (recur (swap! c inc))))
    c))

(go-works?) ;; true

(break-async)

(go-works?) ;; never returns

;; at a fresh repl
(def t-count (count-while-works))
;; wait a second
@t-count ;; stays at 50

Did you know? CLOSE

  • There are keyboard shortcuts!
    • When Creating A Paste
      • ALT+P Toggle Private
      • CTRL+Enter Create Paste
      • ALT+W Toggle word wrap
    • When Viewing A Paste
      • ALT+G Go to a line
      • ALT+CTRL+E Edit the paste
      • ALT+R Show the raw code
  • There are URL options!
    • When Creating A Paste
      • ?lang=Javascript to default to javascript
    • When Viewing A Paste
      • #L-N Jump to line number N
?