-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow channels to be closed on blocking select #8243
Conversation
As a comparison to Go, select {
case m, e := <-c:
// ...
} when the channel is closed, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no spec for all channels being closed running the else
?
end | ||
state = Atomic(SelectState).new(SelectState::Active) | ||
all_closed = true | ||
contexts = ops.map_with_index do |op, index| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The index is never used?
if has_else | ||
return ops.size, NotReady | ||
else | ||
raise "All channels are closed on a blocking select" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should raise ClosedError.new
, exactly as if you had used receive
on any one of the closed channels.
ideally this would be designed to literally call ch.receive
on the last channel to be closed, as that's semantically what's happening on my head, but that's not feasible.
We were discussing with @waj about the design. Another idea is that instead of going the route of this PR, the This will be actually more similar to Go in the sense that a close event will awake the select, but will keep the simple API for when the user does not care about channel been closed. A Regarding the a) It returns a b) It returns a |
I didn't see It would also be great to document more Channel in the API docs, and the book. People are certainly missing powerful Channel features. I did try, but I don't know the topic well enough 🤐 |
@bcardiff I like the simple design: wake up the select, let For the alternatives, the case of |
@ysbaddaden that won't work. It is not possible to effectively use That why the alternative is to either a) use b) introduce Either way, an independent |
An alternative is |
I've been iterating on this. As said before
The current review of what types is expected can be viewed at: https://gist.github.com/bcardiff/289953a80eb3a0512a2a2f8c8dfeb1db Closing this PR. I should submit a new one with the above implementation. |
This PR might deserve a bit of discussion. On the MT recent work, we focus on non-blocking select and I think there were some cases for blocking select that might have slipped.
is equivalent to
and to
And it is expected to wait for a
send
over anych1
andch2
.Then, there is a construct for non-blocking
select
(when anelse
is present):Or equivalent:
For non-blocking
select
there is no change in the behaviour in this PR.For blocking
select
, since closing a channel awakes the fiber, there is a need to loop and re-wait over the channels. This is what is mainly added in this PR.A decision was made regarding what should happen on blocking select over closed channels: It will generate a runtime exception with the message "All channels are closed on a blocking select".
Additionally, we avoid waiting over already closed channels.
Related to #8231, but the opening issue will still raise since it was a blocking select over a closed channel. But it pushed the think exposed here in the specs.