>
> No code called by a go block should ever call the blocking variants of 
> core.async functions (<!!, >!!, alts!!, etc.). So I'd start at the code 
> redacted in those lines and go from there.
>

Seems like a good use case for a static code analyser.  Maybe a 
contribution to https://github.com/jonase/eastwood

On Tuesday, 29 August 2017 14:40:08 UTC-7, Alex Miller wrote:
>
> We did actually discuss doing something like this a long time ago. The 
> worry that comes to mind is whether it should actually be forbidden (an 
> invariant) or merely strong frowned upon. It is possible to arrange a 
> situation where you know (based on other knowledge) that a put on a channel 
> will succeed. Should that be allowed? I'd have to hammock on that one for a 
> while.
>
> On Tuesday, August 29, 2017 at 3:19:51 PM UTC-5, Aaron Iba wrote:
>>
>> Ahh that makes a lot of sense.  Indeed, I'm guilty of doing a blocking 
>> >!! inside a go-block.  I was so careful to avoid other kinds of blocking 
>> calls (like IO) that I forgot that blocking variants of core.async calls 
>> themselves were forbidden.
>>
>> Thank you for pointing this out!  I will rewire things to not do this.
>>
>> Per Gary's suggestion, I also think it'd be useful if core.async blocking 
>> ops checked a dynamic var (or a property of the thread itself) and at least 
>> warned if they are being called from a forbidden context.  To resolve my 
>> original issue, I'm considering doing this in my dev environment:
>>
>> (doseq [v '[<!! >!!]]
>>   (alter-var-root (ns-resolve 'clojure.core.async v)
>>                   (fn [f]
>>                     (fn [& args]
>>                       (if (.startsWith (.getName (Thread/currentThread))
>>                                        "async-dispatch-")
>>                         (throw (Exception. (str v " called inside 
>> async-dispatch")))
>>                         (apply f args))))))
>>
>>
>>
>>
>> On Tuesday, August 29, 2017 at 1:43:53 PM UTC-4, Gary Trakhman wrote:
>>>
>>> Hm, I came across a similar ordering invariant (No code called by a go 
>>> block should ever call the blocking variants of core.async functions) while 
>>> wrapping an imperative API, and I thought it might be useful to use 
>>> vars/binding to enforce it.  Has this or other approaches been considered 
>>> in core.async?  I could see a *fixed-thread-pool* var being set and >!! 
>>> checking for false.
>>>
>>> An analogy in existing clojure.core would be the STM commute's 'must be 
>>> running in a transaction' check that uses a threadlocal. 
>>> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L205
>>>
>>> On Tue, Aug 29, 2017 at 1:30 PM Timothy Baldridge <tbald...@gmail.com> 
>>> wrote:
>>>
>>>> To add to what Alex said, look at this trace: 
>>>> https://gist.github.com/anonymous/65049ffdd37d43df8f23630928e8fed0#file-thread-dump-out-L1337-L1372
>>>>
>>>> Here we see a go block calling mapcat, and inside the inner map 
>>>> something is calling >!!. As Alex mentioned this can be a source of 
>>>> deadlocks. No code called by a go block should ever call the blocking 
>>>> variants of core.async functions (<!!, >!!, alts!!, etc.). So I'd start at 
>>>> the code redacted in those lines and go from there. 
>>>>
>>>>
>>>>
>>>> On Tue, Aug 29, 2017 at 11:09 AM, Alex Miller <al...@puredanger.com> 
>>>> wrote:
>>>>
>>>>> go blocks are multiplexed over a thread pool which has (by default) 8 
>>>>> threads. You should never perform any kind of blocking activity inside a 
>>>>> go 
>>>>> block, because if every go block in work happens to end up blocked, you 
>>>>> will prevent all go blocks from making any further progress. It sounds to 
>>>>> me like that's what has happened here. The go block threads are named 
>>>>> "async-dispatch-<n>" and it looks like there are 8 blocked ones in your 
>>>>> thread dump.
>>>>>
>>>>> It also looks like they are all blocking on a >!!, which is a blocking 
>>>>> call. So I would look for a go block that contains a >!! and convert that 
>>>>> to a >! or do something else to avoid blocking there.
>>>>>
>>>>>
>>>>> On Tuesday, August 29, 2017 at 11:48:25 AM UTC-5, Aaron Iba wrote:
>>>>>>
>>>>>> My company has a production system that uses core.async extensively. 
>>>>>> We've been running it 24/7 for over a year with occasional restarts to 
>>>>>> update things and add features, and so far core.async has been working 
>>>>>> great.
>>>>>>
>>>>>> The other day, during a particularly high workload, the whole system 
>>>>>> got locked up. All the channels seemed blocked at once.  I was able to 
>>>>>> connect with a REPL and poke around, and noticed strange behavior of 
>>>>>> core.async. Specifically, the following code, when evaluated in the 
>>>>>> REPL, 
>>>>>> blocked on the put (third expression):
>>>>>>
>>>>>> (def c (async/chan))
>>>>>> (go-loop []
>>>>>>   (when-some [x (<! c)]
>>>>>>     (println x)
>>>>>>     (recur)))
>>>>>> (>!! c true)
>>>>>>
>>>>>> Whereas on any fresh system, the above expressions obviously succeed.
>>>>>>
>>>>>> Puts succeeded if they went onto the channel's buffer, but not when 
>>>>>> they should go through to a consumer. For example with the following 
>>>>>> expressions, evaluated in the REPL, the first put succeeded (presumably 
>>>>>> because it went on the buffer), but subsequent puts blocked:
>>>>>>
>>>>>> (def c (async/chan 1))
>>>>>> (def m (async/mult c))
>>>>>> (def out (async/chan (async/sliding-buffer 3)))
>>>>>> (async/tap m out)
>>>>>> (>!! c true) ;; succeeds
>>>>>> (>!! c true) ;; blocks forever
>>>>>>
>>>>>> This leads me to wonder if core.async itself somehow got into a bad 
>>>>>> state. It's entirely possible I caused this by misusing the API 
>>>>>> somewhere 
>>>>>> in the codebase, but we use core.async so extensively that I wouldn't 
>>>>>> know 
>>>>>> where to begin looking.
>>>>>>
>>>>>> I'm wondering if someone more familiar with core.async internals has 
>>>>>> an idea about what could cause the above situation. Or if we notice it 
>>>>>> happening again, what could I do to gather more helpful information.
>>>>>>
>>>>>> I also have a redacted thread dump, in case it's useful:
>>>>>>
>>>>>> https://gist.github.com/anonymous/65049ffdd37d43df8f23630928e8fed0
>>>>>>
>>>>>> Any help would be much appreciated,
>>>>>>
>>>>>> Aaron
>>>>>>
>>>>>> P.S. core.async has been a godsend in terms of helping us structure 
>>>>>> and modularize our large system.  Thank you to all those who contributed 
>>>>>> to 
>>>>>> this wonderful library!
>>>>>>
>>>>>> -- 
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Clojure" group.
>>>>> To post to this group, send email to clo...@googlegroups.com
>>>>> Note that posts from new members are moderated - please be patient 
>>>>> with your first post.
>>>>> To unsubscribe from this group, send email to
>>>>> clojure+u...@googlegroups.com
>>>>> For more options, visit this group at
>>>>> http://groups.google.com/group/clojure?hl=en
>>>>> --- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "Clojure" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to clojure+u...@googlegroups.com.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>
>>>>
>>>> -- 
>>>> “One of the main causes of the fall of the Roman Empire was 
>>>> that–lacking zero–they had no way to indicate successful termination of 
>>>> their C programs.”
>>>> (Robert Firth) 
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with 
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to clojure+u...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to