smol-rs / futures-lite

Futures, streams, and async I/O combinators.
Apache License 2.0
427 stars 25 forks source link

`select!` & `select_biased!` as in `futures-util` #65

Closed stackinspector closed 1 year ago

stackinspector commented 1 year ago

I don't seem to find an equivalent for select! and select_biased! in the smol ecosystem. If it exists, please point it out. If it doesn't exist, can I use the one in futures-util for now? Will it cause incompatibility to use only this macro and fuse() with FutureExt?

notgull commented 1 year ago

The or or race methods can be used to only select one of two futures. However, if these don't work for you, there's no reason why you can't use the macro from futures-util.

stackinspector commented 1 year ago

So how to perform different actions in each future polled? Is there an operator like "then"?

notgull commented 1 year ago

My personal strategy is to use an async block to combine the future with a result that can be pattern-matched on. For instance:

use either::Either;

let a = async { /* ... */ };
let b = async { /* ... */ };

// Wrap them so that they return one-half of an `Either`.
let a_wrapped = async { Either::Left(a.await) };
let b_wrapped = async { Either::Right(b.await) };

// Run the futures, select only one, then wait on the result.
let result = a_wrapped.or(b_wrapped).await;
match result {
    Either::Left(a_result) => { /* ... */ },
    Either::Right(b_result) => { /* ... */ },
}
stackinspector commented 1 year ago

My personal strategy is to use an async block to combine the future with a result that can be pattern-matched on. For instance:

use either::Either;

let a = async { /* ... */ };
let b = async { /* ... */ };

// Wrap them so that they return one-half of an `Either`.
let a_wrapped = async { Either::Left(a.await) };
let b_wrapped = async { Either::Right(b.await) };

// Run the futures, select only one, then wait on the result.
let result = a_wrapped.or(b_wrapped).await;
match result {
    Either::Left(a_result) => { /* ... */ },
    Either::Right(b_result) => { /* ... */ },
}

It seems that the code generated by select! does the same thing internally. I found something related to generating enum when I search in the source code.

notgull commented 1 year ago

The point of this crate is to provide a better experience than the futures crate, and I think that macros like this tend to worsen the experience. See this comment for more information. Unless there is a large demand for it, as it can be replicated trivially using patterns currently in this crate, I think we are unlikely to add this in the future.

notgull commented 1 year ago

Closing this issue since we don't plan on adding this.

nanoqsh commented 7 months ago

Can I run race for three futures fairly?

notgull commented 7 months ago

Can I run race for three futures fairly?

Not with this crate, and you don't want to combine that many futures without an executor.

nanoqsh commented 7 months ago

you don't want to combine that many futures without an executor

How can this problem be solved, for example, in smol?