Skip to content
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

Expose channel index in receive_first and send_first? #10411

Open
bcardiff opened this issue Feb 18, 2021 · 2 comments
Open

Expose channel index in receive_first and send_first? #10411

bcardiff opened this issue Feb 18, 2021 · 2 comments

Comments

@bcardiff
Copy link
Member

When wanting to wait for multiple channel operations a select expression is suggested.

select
when a = ch1.receive
  # ...
when b = ch2.receive
  # ...
end

If the user has an Array of channels it need to be use a_or_b = Channel.receive_first(channels) or use the no-doc api Channel#select/Channel#non_blocking_select.

It bugs me that Channel.receive_first/Channel.send_first will not tell you on which channel the operation was performed. With Channel#select/Channel#non_blocking_select you have that information: {index, data} and with a select expression you know that implicitly because of which when is executed.

  • Should Channel.receive_first return {index, data} instead of only data?
  • Should Channel.send_first return index instead of only Nil?
@straight-shoota
Copy link
Member

A similar proposal was made by @joatca in #6657:

Channel.receive_first and Channel.send_first discard the index returned by the underlying Channel.select. To handle cases where the channel that performed an operation is significant, I propose Channel.receive_first_with_index for receiving and either a new method Channel.send_first_index or returning the index directly from Channel.send_first and allowing using code to discard it. The discussion at crystal-lang/crystal-book#279 (review) suggests that Channel.select is intended as a low-level interface and that the *_first methods are considered the high-level interface.

@straight-shoota
Copy link
Member

Changing the return type of at least .receive_first would be a backwards-incompatible breaking change.

To avoid that we need a different signature. .receive_first_with_index and .send_first_with_index seems like a good choice.

An alternative that could be worth considering is to expose the currently internal API Channel.select as well as the *_select_action methods. This would allow more flexible and powerful use cases, such as a dynamically allocated action list that's not homogenously send or receive on different channels.
Not sure if there's a real use case for that, though. And .receive_first_with_index and .send_first_with_index could still be useful for convenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants