pending puts are never signalled when channels are closed


Putting on a closed channel should ensure that the producer's put callback be notified with false when a channel is closed.
Currently that is the case when the channel is closed prior to a value being produced on the channel.

When using fixed buffers, there is a race condition if the following sequence of operations occur:

  • A buffer gets filled up

  • A subsequent put blocks, waiting for the buffer to recover capacity

  • The channel is closed

In this case, a put! operation will never see its callback being called, nor would a greater-than-bang! or greater-than-bang-bang! operation ever return (can't figure out the correct way to mark those in JIRA's markup).
From the documenation, the correct behavior should be to deliver false to the put callback.

Here is a small reproduction example:


Unless I am misunderstanding the semantics or intended behavior of put, I have a fix which walks the list of pending puts when a
close operation occurs on a channel and delivers false to the list of putter callbacks, as well as a corresponding test case. You'll find both as attached files.

If this is deemed valid I can see if the CLJS part also suffers from the same behavior (which at a quick glance seems to be the case).

As it stands, CLJS seems unaffected by the issue, as evidenced by the test I attached to this issue.


Reproduced with core.async 0.3.365 and 0.4.474


Pierre-Yves Ritschard
February 16, 2018, 3:19 PM

So as it turns out, one way to deal with this is to drain the closed channel, like so:

This ensures no pending puts are blocked. Thanks go out to Tim Baldridge and Alex Miller for helping reason around the issue.

Your pinned fields
Click on the next to a field label to start pinning.




Pierre-Yves Ritschard