-
Notifications
You must be signed in to change notification settings - Fork 634
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
select! without FusedFuture #1989
Comments
Just figured out But I think selecting on |
Just another syntax idea to make sure arbitrary expressions that resolve to a Instead of passing the Stream to the disabler this just gets a plain struct. And instead disabling is performed in a fashion that is similar to if clauses on asnyc fn merge(a_stream: Receiver<i32>, b_stream: Receiver<i32>) -> Receiver<i32> {
let (sender, receiver) = channel();
spawn(async {
let a_disabler = SelectDisabler::new();
let b_disabler = SelectDisabler::new();
while a.is_enabled() && b.is_enabled() {
select! {
a_result = a_stream.next() if_enabled(a_disabler) => {
match a_result {
Some(v) => sender.send(v).await,
None => {
// Disable the branch
a_disabler.disable();
}
}
}
b_result = b_stream.next() if_enabled(b_disabler) => {
match b_result {
Some(v) => sender.send(v).await,
None => {
// Disable the branch
b_disabler.disable();
}
}
}
}
}
});
receiver
} |
https://github.com/tekjar/rumq/blob/master/rumq-client/src/eventloop.rs#L169-L172 Conditional branch polling helped me in implementing a very readable flow control based on current inflight queue size. Any plans to bring this feature to futures |
@tekjar I'd be happy to accept a PR! I don't personally have the bandwidth to implement it myself at the moment, sorry. |
An even simpler alternative would be to allow selecting on an Please also note that selecting on |
With |
select!
is probably my favorite API in the whole Rust async story. That is because it enables use-cases that are not possible in normal threaded code: We can wait on arbitrary operations to complete concurrently (not only on channels) - and depending on the result and current state even cancel some of the branches.I think the most recent changes which allowed to
select!
on non-pinned Futures made this operations already a fair bit more accessible for most users, since they now do not need to deal with pinning in most cases.I'm now thinking about whether we could not still improve in another area:
Fusing
. The requirement that branches need to implementFusedFuture
imposes 2 downsides:FusedFuture
thing actually is, and add.fuse()
to most of their statements (since they might be coming from anasync fn
).FusedFuture
directly (since it's more correct and more ergonomic) must take a dependency onfuture-core
. Which some libraries that have a zero-dependency policy or which are unhappy thatfutures-rs
is still not 1.0 want to avoid.I am not contemplating whether the use-cases for which
FusedFuture
inselect!
is required could not be also supported in another fashion - which has different trade-offs.First of all regarding the use-cases: I think the main use-case for fusing is to selectively disable branches inside
select!
, which prevents busy-looping. It is in that sense similar to the Go pattern of selecting onnil
channels, which disables aselect
branch. I think theselect!
macro could support selective branches in a similar fashion: By enabling or disabling individual branches of aselect!
by user function calls (instead of automatically disabling them based on previous observation that the branch terminated).In order to enable/disable branches users would need to store the
Stream
orFuture
for these branches in a certain Switch/Option type which is known to the macroTranslating the Go example from the Link, it could look along
With such an API the
terminated
branch obviously only makes sense if all branches in theselect!
support disabling.Benefits:
.fuse()
anymore in commonselect!
use-cases. Directly selecting onFuture
s andStream
s would just work, unless people need selective disabling (which the minority probably do).FusedFuture
and could potentially avoid being dependent onfutures-core
forselect
compatibility.Drawbacks:
FusedFuture
information anymore is one. And thereby software which relied on it would no longer work the same. I'm however not really sure if a lot of that is out there.Future/Stream
implementations doing it automatically.WDYT @cramertj , @Nemo157 , @taiki-e
The text was updated successfully, but these errors were encountered: