Description
Selecting over >=2 futures has subtle fairness issues when more than one future is ready. The current offering has a few inconsistencies in docs and naming:
futures::select!
: pseudo-random, documentedfutures::select_biased!
: in-order, documentedfutures::future::{select, try_select, select_ok}
: in-order, undocumentedfutures::future::select_all
: in-order, documented that one should not rely on orderfutures::stream::select
: round-robin, documentedfutures::stream::select_all
: (based on FuturesUnordered - not sure), undocumented
Golang uses random order for select
to prevent starvation, which is a hard-to-detect and problematic pitfall. IMO, any select API with a starvation risk should be explicitly documented as such. Even "don't rely on order" is too benign of a statement.
For user-facing behavior, I'd divide the behavior of the current offering into three classes:
- Order specified in the API. (2)
- Order not specified, but has mitigations against starvation. (1, 5, 6?)
- Order not specified, but can cause starvation. (3, 4)
- Ideally I'd suggest eliminating this class entirely in favor of either of the other two
Initially, adding coverage of these behaviors to the existing API docstrings would be nice. Happy to create a PR upon endorsement from a maintainer.
Regarding naming, I like the precedent set by the macros: select!
is starvation-protected by default, and select_biased!
has explicit ordering. Following the principle of least surprise, ideally that convention could be applied to the other APIs as well. Now, going down this road would introduce breaking changes. Maybe a maintainer can chime in?