From d51a246fc8b68e4292d6e99fa69ba0c73bf5a91f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 18:09:24 -0400 Subject: [PATCH 01/19] first draft of async project goal --- text/0000-async-project-goal-2024h2.md | 263 +++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 text/0000-async-project-goal-2024h2.md diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md new file mode 100644 index 00000000000..9e182035bd4 --- /dev/null +++ b/text/0000-async-project-goal-2024h2.md @@ -0,0 +1,263 @@ +- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) +- Start Date: (fill me in with today's date, YYYY-MM-DD) +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) +- Goal owners: [tmandry][], [nikomatsakis][] +- Goal teams: [Lang], [Libs-API] + +# Summary +[summary]: #summary + +This is a proposed flagship goal for 2024h2 covering **async Rust**. You can [read more about the project goal slate and its associated process here](https://rust-lang.github.io/rust-project-goals/2024h2/slate.html). This RFC is prepared using the project goal template, which differs from the typical RFC template. + +The overall goal is **bringing the Async Rust experience closer to parity with sync Rust** via the following steps: + +* stabilizing async closures, thus enabling richer, combinator APIs like sync Rust's [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html); +* [resolving the "send bound problem"](#resolve-the-send-bound-problem), thus enabling foundational, generic traits like Tower's [`Service`]() trait; +* [stabilizing a trait in libstd for async iteration](#stabilize-trait-for-async-iteration), thus enabling the ecosystem to build atop a stable foundation; +* [authoring a draft RFC for async vision](#author-draft-rfc-for-async-vision), thus aligning the project around a coherent vision; +* [completing the async drop experiments](#complete-async-drop-experiments) proposed in [MCP 727][], laying the groundwork for resolving the the next most + +# Motivation + +In 2024 we plan to deliver several critical async Rust building block features, most notably support for *async closures* and *`Send` bounds*. This is part of a multi-year program aiming to raise the experience of authoring "async Rust" to the same level of quality as "sync Rust". Async Rust is a crucial growth area, with 52% of the respondents in the [2023 Rust survey](https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html) indicating that they use Rust to build server-side or backend applications. + +## The status quo + +### Async Rust performs great, but can be hard to use + +Async Rust is the most common Rust application area according to our [2023 Rust survey](https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html). Rust is a great fit for networked systems, especially in the extremes: + +* **Rust scales up**. Async Rust reduces cost for large dataplanes because a single server can serve high load without significantly increasing tail latency. +* **Rust scales down.** Async Rust can be run without requiring a garbage collector or [even an operating system][embassy], making it a great fit for embedded systems. +* **Rust is reliable.** Networked services run 24/7, so Rust's "if it compiles, it works" mantra means unexpected failures and, in turn, fewer pages in the middle of the night. + +Despite async Rust's popularity, using async I/O makes Rust significantly harder to use. As one Rust user memorably put it, "Async Rust is Rust on hard mode." Several years back the async working group collected a number of ["status quo" stories](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo.html) as part of authoring an async vision doc. These stories reveal a number of characteristic challenges: + +* Common language features like ~~[traits](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_needs_async_in_traits.html)~~ (they [do now][afitblog], though gaps remain), closures, and [drop](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_finds_database_drops_hard.html) do not support async, meaning that [users cannot write Rust code in the way they are accustomed to](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_plays_with_async.html?highlight=closure#the-story). In many cases there are workarounds or crates that can close the gap, but users have to learn about and find those crates. +* Common async idioms have "sharp edges" that lead to unexpected failures, forcing users to manage [cancellation safety](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_gets_burned_by_select.html), subtle [deadlocks](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/aws_engineer/solving_a_deadlock.html) and other failure modes for [buffered streams](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_battles_buffered_streams.html). See also tmandry's blog post on [Making async Rust reliable](https://tmandry.gitlab.io/blog/posts/making-async-reliable/)). +* Using async today requires users to select a runtime which provides many of the core primitives. Selecting a runtime as a user [can be stressful](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_makes_their_first_steps_into_async.html#the-wrong-time-for-big-decisions), as the [decision once made is hard to reverse](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_wishes_for_easy_runtime_switch.html). Moreover, in an attempt to avoid "picking favories", the project has not endorsed a particular runtime, making it [harder to write new user documentation](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/niklaus_wants_to_share_knowledge.html). Libaries meanwhile [cannot easily be made interoperable across runtimes](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_writes_a_runtime_agnostic_lib.html) and so are often written against the API of a particular runtime; even when libraries can be retargeted, it is difficult to do things like run their test suites to test compatibility. [Mixing and matching libraries can cause surprising failures.](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_started_trusting_the_rust_compiler_but_then_async.html) + +[afitblog]: https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html +[embassy]: https://github.com/embassy-rs/embassy +[tokio]: https://tokio.rs/ + +### First focus: language parity, interop traits + +Based on the above analysis, the Rust org has been focused on driving async/sync language parity, especially in those areas that block the development of a rich ecosystem. The biggest progress took place in [Dec 2023][afitblog], when async fn in traits and return position impl trait in trait were stabilizd. Other work includes authoring the async vision doc, stabilizing helpers like [`std::future::poll_fn`](https://doc.rust-lang.org/std/future/fn.poll_fn.html)), and polishing and improving async error messages. + +### Lack of internal alignment within the Rust org about the direction for async + +Progress on async-related issues within the Rust org has been slowed due to lack of coherence around a vision and clear steps. Discussion gets stuck not only on technical details but also on what problems to be resolving first. The lack of a centrally agreed upon vision has also made it hard for general purpose teams such as [Lang][] or [Libs-API][] to decide how to respond to requests to e.g. stabilize particular async-related constructs, as they lack a means to judge whether stabilizing any particular construct is really the right step forward and whether it meets its design needs. + +## The next few steps + +In the second half of 2024 we are planning on the following work items: + +* [stabilize async closures](#stabilize-async-closures) +* [resolve the "Send bound" problem](#stabilize-async-closures) +* [stabilize trait for async iteration](#stabilize-trait-for-async-iteration) +* [author draft RFC for async vision](#author-draft-rfc-for-async-vision) +* [complete async drop experiments](#complete-async-drop-experiments) (currently unfunded) + +### Stabilize async closures + +Building ergonomic APIs in async is often blocked by the lack of *async closures*. Async combinator-like APIs today typically make use an ordinary Rust closure that returns a future, such as the `filter` API from [`StreamExt`](https://docs.rs/futures/latest/futures/prelude/stream/trait.StreamExt.html#method.filter): + +```rust +fn filter(self, f: F) -> Filter +where + F: FnMut(&Self::Item) -> Fut, + Fut: Future, + Self: Sized, +``` + +This approach however does not allow the closure to access variables captured by reference from its environment: + +```rust +let mut accept_list = vec!["foo", "bar"] +stream + .filter(|s| async { accept_list.contains(s) }) +``` + +The reason is that data captured from the environment is stored in `self`. But the signature for sync closures does not permit the return value (`Self::Output`) to borrow from `self`: + +```rust +trait FnMut: FnOnce { + fn call_mut(&mut self, args: A) -> Self::Output; +} +``` + +To support natural async closures, a trait is needed where `call_mut` is an `async fn`, which would allow the returned future to borrow from `self` and hence modify the environment (e.g., `accept_list`, in our example above). Or, desugared, something that is equivalent to: + +```rust +trait AsyncFnMut: AsyncFnOnce { + fn call_mut<'s>(&'s mut self, args: A) -> use<'s, A> impl Future; + // ^^^^^^^^^^ note that this captures `'s` +} +``` + +The goal for this year to be able to + +* support some "async equivalent" to `Fn`, `FnMut`, and `FnOnce` bounds + * this should be usable in all the usual places +* support some way to author async closure expressions + +These features should be sufficient to support methods like `filter` above. + +The details (syntax, precise semantics) will be determined via experimentation and subject to RFC. + +### Stabilize trait for async iteration + +There has been extensive discussion about the best form of the trait for async iteration (sometimes called `Stream` and sometimes `AsyncIter`). We believe the design space has been sufficiently explored that it should be possible to author an RFC laying out the options and proposing a specific plan. + +### Resolve the ["send bound"][sb] problem + +Although async functions in traits were stabilized, there is currently no way to write a generic function that requires only impls where the returned futures are `Send`. This blocks the use of async function in traits in some core ecosystem crates, such as [tower](https://crates.io/crates/tower), which want to work across all kinds of async executors. This problem is called the ["send bound"][sb] problem and there has been extensive discussion of the various ways to solve it. [RFC #3654][] has been opened proposing one solution and describing why that path is preferred. Our goal for the year is to adopt *some* solution on stable. + +[RFC #3654]: https://github.com/rust-lang/rfcs/pull/3654 + +### Author draft RFC for async vision + +We plan to revise the [Async Vision Doc][AVD] and restructure it as a draft RFC, most likely to be approved by the [Lang][] and [Libs-API][] teams (we do not necessarily expect that RFC to be accepted by end of year). Our observation is that the previous version of the async vision doc, which was never RFC'd, never attained the legitimacy of being the "plan of record". In addition, a number of things have changed in the intervening years (for example, async functions in traits are now stable) and we are in a position to identify clearer next steps. The + +[AVD]: https://rust-lang.github.io/wg-async/vision.html + +This RFC will lay out a "plan of attack" for async, including both obvious good things (similar to [async closures][]) but also "known unknowns" and ways to resolve them. Areas the RFC is expected to cover are as follows: + +[Async Vision Doc]: +[Making Async Rust Reliable]: https://tmandry.gitlab.io/blog/posts/making-async-reliable/ + +* Status quo, covering biggest challenges + * Lack of strong learning material + * Common idioms contain footguns that cause unexpected failures (see e.g., Tyler's blog post [Making Async Rust Reliable][]) + * Low-level performance hurdles, such as large future sizes and downsides of the poll model + * Fragmentation between runtimes +* Design axioms to pursue for async (see e.g. axioms proposed) +* Goals, some variant of + * Free of accidental complexity + * Easy to get started + * Easy to pick executor and integrate with other systems (e.g., mobile runtimes, company-specific threadpools, etc) + * Moderately easy to adapt to "extreme" embedded environments + * Good performance by default, peak performance with tuning +* Key unknowns in terms of how to achieve the above goals, for example + * how to replace footgun-prone APIs with more reliable alternatives: + * buffered-streams, cancellation (esp. due to use of select) + * patterns to express + * merged streams -- processing one stream of data with occasional control events + * task parallelism + * cleanup and teardown + * ordered destruction + * how should async drop work (`?Leak` vs `?Drop` vs whatever): + * how to prevent async drop from occuring in sync contexts? + * what does runtime interface look like? + * Can/should we be generic over runtime +* Strategy for how to get where we are going + * What problems to attack first + * How to reduce or find solutions to the above unknowns + +### Complete async drop experiments + +Authors of async code frequently need to call async functions as part of resource cleanup. Because Rust today only supports synchronous destructors, this cleanup must take place using alternative mechanisms, forcing a divergence between sync Rust (which uses destructors to arrange cleanup) and async Rust. [MCP 727](https://github.com/rust-lang/compiler-team/issues/727) proposed a series of experiments aimed at supporting async drop in the compiler. We would like to continue and complete those experiments. These experiments are aimed at defining how support for async drop will be implemented in the compiler and some possible ways that we could modify the type system to support it (in particular, one key question is how to prevent types that whose drop is async from being dropped in sync code). + +## The "shiny future" we are working towards + +Our eventual goal is to provide Rust users building on async with + +* the same core language capabilities as sync Rust (async traits with dyn dispatch, async closures, async drop, etc); +* reliable and standardized abstractions for async control flow (streams of data, error recovery, concurrent execution); +* an easy "getting started" experience that builds on a rich ecosystem; +* the ability to easily adopt custom runtimes when needed for particular environments, language interop, or specific business needs. + +# Design axiom + +* **We lay the foundations for a thriving ecosystem.** The role of the Rust org is to deelop the rudiments that support an interoperable and thriving async crates.io ecosystem. +* **Uphold sync's Rust bar for reliability.** Sync Rust famously delivers on the general feeling of "if it compiles, in works" -- async Rust should do the same. +* **When in doubt, zero-cost is our compass.** Many of Rust's biggest users are choosing it becase they know it can deliver the same performnace (or better) than C. If we adopt abstractions that add overhead, we are compromising that core strength. As we build out our designs, we ensure that they don't introduce an "abstraction tax" for using them. +* **From embedded to GUI to the cloud.** Async Rust covers a wide variety of use cases and we aim to make designs that can span those differing constraints with ease. +* **Consistent, incremental progress.** People are building async Rust systems *today* -- we need to ship incremental improvements while also steering towards the overall outcome we want. + +# Ownership and other resources + +Here is a detailed list of the work to be done and who is expected to do it. This table includes the work to be done by owners and the work to be done by Rust teams (subject to approval by the team in an RFC/FCP). The overall owners of the async effort (and authors of this goal document) are [tmandry][] and [nikomatsakis][]. We have identified owners for subitems below; these may change over time. + +* The ![Funded][] badge indicates that the owner has committed and work will be funded by their employer or other sources. +* The ![Team][] badge indicates a requirement where Team support is needed. + +| Subgoal | Owner(s) or team(s) | Status | +| ---------------------------------------- | --------------------------------------- | ------------------- | +| overall program management | [tmandry][], [nikomatsakis][] | ![Funded][] | +| stabilize async closures | | ![Funded][] | +| ↳ ~~implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | +| ↳ author RFC | [nikomatsakis][] or [compiler-errors][] | ![Funded][] | +| ↳ approve RFC | ![Team][] [Lang] | ![Not funded][] | +| ↳ stabilization | [compiler-errors][] | ![Not funded][] | +| resolve the ["send bound"][sb] problem | | ![Funded][] | +| ↳ ~~RTN implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | +| ↳ ~~RTN RFC~~ | [nikomatsakis][] | ![Complete][] | +| ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | ![Not funded][] | +| ↳ stabilization | [compiler-errors][] | ![Not funded][] | +| stabilize trait for async iteration | | ![Funded][] | +| ↳ author RFC | [eholk][] | ![Funded][] | +| ↳ approve RFC | ![Team][] [Libs-API] | ![Funded][] | +| ↳ implementation | [eholk][] | ![Funded][] | +| author draft RFC for async vision | | ![Funded][] | +| ↳ author RFC | [tmandry][] | ![Funded][] | +| ↳ approve RFC | ![Team][] [Lang], [Libs-API] | ![Not approved][] | +| complete async drop experiments | | | +| ↳ ~~author MCP~~ | ~~[petrochenkov][]~~ | ![Complete][] | +| ↳ ~~approve MCP~~ | ~~[Compiler]~~ | ![Complete][] | +| ↳ implementation work | [petrochenkov][] | ![Not funded][] (*) | + +(*) Implementation work on async drop experiments is currently unfunded. We are trying to figure out next steps. + +[Funded]: https://img.shields.io/badge/Funded-yellow +[Not funded]: https://img.shields.io/badge/Not%20yet%20funded-red +[Approved]: https://img.shields.io/badge/Approved-green +[Not approved]: https://img.shields.io/badge/Not%20yet%20approved-red +[Complete]: https://img.shields.io/badge/Complete-green +[TBD]: https://img.shields.io/badge/TBD-red +[Team]: https://img.shields.io/badge/Team%20ask-red + +## Support needed from the project + +Agreement from [Lang] and [Libs-API] to the items marked ![Team][] in the table above. Potentially other design meetings as needed. + +Expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. + +# Outputs and milestones + +Stabilized features for + +* async closures +* a ["send bound"][sb] solution, most likely [RTN][] + +# Frequently asked questions + +## Why focus on send bounds + async closures? + +These are the two features that together block the authoring of traits for a number of common interop purposes. Send bounds are needed for generic traits like the `Service` trait. Async closures are needed for rich combinator APIs like iterators. + +## Why not work on dyn dispatch for async fn in traits? + +Async fn in traits do not currently support native dynamic dispatch. We have explored a [number of designs for making it work](https://smallcultfollowing.com/babysteps/blog/2021/09/30/dyn-async-traits-part-1/) but are not currently prioritizing that effort. It was determined that this idea is lower priority because it is possible to [workaround](https://smallcultfollowing.com/babysteps/blog/2021/10/15/dyn-async-traits-part-6/) the gap by having the `#[trait_variant]` crate produce a dynamic dispatch wrapper type (e.g., `#[trait_variant(dyn = DynWidget)] trait Widget` would create a type `DynWidget<'_>` that acts like a `Box`). We do expect to support dyn async trait, hopefully in 2025. + +## Why are we moving forward on a trait for async iteration? + +There has been extensive discussion about the best design for the "Stream" or "async iter" trait and we judge that the design space is well understood. We would like to unblock generator syntax in 2025 which will require some form of trait. + +The majority of the debate about the trait has been on the topic of whether to base the trait on a `poll_next` function, as we do today, or to try and make the trait use `async fn next`, making it more anaologous with the `Iterator` trait (and potentially even making it be two versions of a single trait). We will definitely explore forwards compatibility questions as part of this discussion. nikomatsakis for example still wants to explore maybe-async-like designs, especially for combinator APIs like `map`. However, we also refer to the design axiom that that "when in doubt, zero-cost is our compass" -- we believe we should be able to stabilize a trait that does the low-level details right, and then design higher level APIs atop that. + +## Why work on a revised async vision doc? Don't we already have one? + +The existing doc was authored some time back and is in need of an update. Moreover, the original doc was never RFC'd and we have found that it lacks a certain measure of "authority" as a result. We would like to drive stronger alignment on the path forward so that we can focus more on execution. + +## What about "maybe async", effect systems, and keyword generics? + +Keyword generics is an ambitious initiative to enable code that is "maybe async". It has generated significant controversy, with some people feeling it is necessary for Rust to scale and others judging it to be overly complex. We anticipate having more debate on this topic as part of drafting the async vision doc. + +[tmandry]: https://github.com/tmandry +[nikomatsakis]: https://github.com/nikomatsakis +[compiler-errors]: https://github.com/compiler-errors +[eholk]: https://github.com/eholk +[petrochenkov]: https://github.com/petrochenkov From 05649b25128336e9918510b460cd7ab77253d87a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 18:39:28 -0400 Subject: [PATCH 02/19] improve summary --- text/0000-async-project-goal-2024h2.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 9e182035bd4..1b49d3196a9 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -16,7 +16,9 @@ The overall goal is **bringing the Async Rust experience closer to parity with s * [resolving the "send bound problem"](#resolve-the-send-bound-problem), thus enabling foundational, generic traits like Tower's [`Service`]() trait; * [stabilizing a trait in libstd for async iteration](#stabilize-trait-for-async-iteration), thus enabling the ecosystem to build atop a stable foundation; * [authoring a draft RFC for async vision](#author-draft-rfc-for-async-vision), thus aligning the project around a coherent vision; -* [completing the async drop experiments](#complete-async-drop-experiments) proposed in [MCP 727][], laying the groundwork for resolving the the next most +* [completing the async drop experiments](#complete-async-drop-experiments) proposed in [MCP 727][], laying the groundwork for resolving the the next major gap in language feature support. + +Approving this goal implies agreement from the [Lang][] and [Libs-API][] team to the items marked as ![Team][] in the table of work items, along with potentially other design meetings as needed. The expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. # Motivation From e9168327c6bdb0ca7ca3ea85f5df9a4db2bd0c12 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 21:20:12 -0400 Subject: [PATCH 03/19] fix links --- text/0000-async-project-goal-2024h2.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 1b49d3196a9..bf12f22a4d6 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -20,6 +20,11 @@ The overall goal is **bringing the Async Rust experience closer to parity with s Approving this goal implies agreement from the [Lang][] and [Libs-API][] team to the items marked as ![Team][] in the table of work items, along with potentially other design meetings as needed. The expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. +[Team]: https://img.shields.io/badge/Team%20ask-red +[MCP 727]: https://github.com/rust-lang/compiler-team/issues/727 +[Lang]: https://www.rust-lang.org/governance/teams/lang +[Libs-API]: https://www.rust-lang.org/governance/teams/library#team-libs-api + # Motivation In 2024 we plan to deliver several critical async Rust building block features, most notably support for *async closures* and *`Send` bounds*. This is part of a multi-year program aiming to raise the experience of authoring "async Rust" to the same level of quality as "sync Rust". Async Rust is a crucial growth area, with 52% of the respondents in the [2023 Rust survey](https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html) indicating that they use Rust to build server-side or backend applications. @@ -160,7 +165,7 @@ This RFC will lay out a "plan of attack" for async, including both obvious good ### Complete async drop experiments -Authors of async code frequently need to call async functions as part of resource cleanup. Because Rust today only supports synchronous destructors, this cleanup must take place using alternative mechanisms, forcing a divergence between sync Rust (which uses destructors to arrange cleanup) and async Rust. [MCP 727](https://github.com/rust-lang/compiler-team/issues/727) proposed a series of experiments aimed at supporting async drop in the compiler. We would like to continue and complete those experiments. These experiments are aimed at defining how support for async drop will be implemented in the compiler and some possible ways that we could modify the type system to support it (in particular, one key question is how to prevent types that whose drop is async from being dropped in sync code). +Authors of async code frequently need to call async functions as part of resource cleanup. Because Rust today only supports synchronous destructors, this cleanup must take place using alternative mechanisms, forcing a divergence between sync Rust (which uses destructors to arrange cleanup) and async Rust. [MCP 727][] proposed a series of experiments aimed at supporting async drop in the compiler. We would like to continue and complete those experiments. These experiments are aimed at defining how support for async drop will be implemented in the compiler and some possible ways that we could modify the type system to support it (in particular, one key question is how to prevent types that whose drop is async from being dropped in sync code). ## The "shiny future" we are working towards @@ -219,7 +224,7 @@ Here is a detailed list of the work to be done and who is expected to do it. Thi [Not approved]: https://img.shields.io/badge/Not%20yet%20approved-red [Complete]: https://img.shields.io/badge/Complete-green [TBD]: https://img.shields.io/badge/TBD-red -[Team]: https://img.shields.io/badge/Team%20ask-red + ## Support needed from the project From 3108647af9ab8d4d974393a6860fd349413da6c6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 21:22:31 -0400 Subject: [PATCH 04/19] fix few notes --- text/0000-async-project-goal-2024h2.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index bf12f22a4d6..336a84cc8cc 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -99,8 +99,14 @@ To support natural async closures, a trait is needed where `call_mut` is an `asy ```rust trait AsyncFnMut: AsyncFnOnce { - fn call_mut<'s>(&'s mut self, args: A) -> use<'s, A> impl Future; + fn call_mut<'s>( + &'s mut self, + args: A + ) -> impl Future + use<'s, A>; // ^^^^^^^^^^ note that this captures `'s` + // + // (This precise capturing syntax is unstable and covered by + // rust-lang/rust#123432). } ``` @@ -116,7 +122,7 @@ The details (syntax, precise semantics) will be determined via experimentation a ### Stabilize trait for async iteration -There has been extensive discussion about the best form of the trait for async iteration (sometimes called `Stream` and sometimes `AsyncIter`). We believe the design space has been sufficiently explored that it should be possible to author an RFC laying out the options and proposing a specific plan. +There has been extensive discussion about the best form of the trait for async iteration (sometimes called `Stream`, sometimes `AsyncIter`, and now being called `AsyncGen`). We believe the design space has been sufficiently explored that it should be possible to author an RFC laying out the options and proposing a specific plan. ### Resolve the ["send bound"][sb] problem From 6222764b8b2c1d577e74a50d86dc7fab0e93e1a5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 21:39:27 -0400 Subject: [PATCH 05/19] fix some links --- text/0000-async-project-goal-2024h2.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 336a84cc8cc..6203904d4dd 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -20,11 +20,6 @@ The overall goal is **bringing the Async Rust experience closer to parity with s Approving this goal implies agreement from the [Lang][] and [Libs-API][] team to the items marked as ![Team][] in the table of work items, along with potentially other design meetings as needed. The expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. -[Team]: https://img.shields.io/badge/Team%20ask-red -[MCP 727]: https://github.com/rust-lang/compiler-team/issues/727 -[Lang]: https://www.rust-lang.org/governance/teams/lang -[Libs-API]: https://www.rust-lang.org/governance/teams/library#team-libs-api - # Motivation In 2024 we plan to deliver several critical async Rust building block features, most notably support for *async closures* and *`Send` bounds*. This is part of a multi-year program aiming to raise the experience of authoring "async Rust" to the same level of quality as "sync Rust". Async Rust is a crucial growth area, with 52% of the respondents in the [2023 Rust survey](https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html) indicating that they use Rust to build server-side or backend applications. @@ -138,7 +133,6 @@ We plan to revise the [Async Vision Doc][AVD] and restructure it as a draft RFC, This RFC will lay out a "plan of attack" for async, including both obvious good things (similar to [async closures][]) but also "known unknowns" and ways to resolve them. Areas the RFC is expected to cover are as follows: -[Async Vision Doc]: [Making Async Rust Reliable]: https://tmandry.gitlab.io/blog/posts/making-async-reliable/ * Status quo, covering biggest challenges @@ -274,3 +268,8 @@ Keyword generics is an ambitious initiative to enable code that is "maybe async" [compiler-errors]: https://github.com/compiler-errors [eholk]: https://github.com/eholk [petrochenkov]: https://github.com/petrochenkov +[Team]: https://img.shields.io/badge/Team%20ask-red +[MCP 727]: https://github.com/rust-lang/compiler-team/issues/727 +[Lang]: https://www.rust-lang.org/governance/teams/lang +[Libs-API]: https://www.rust-lang.org/governance/teams/library#team-libs-api +[sb]: https://smallcultfollowing.com/babysteps/blog/2023/02/01/async-trait-send-bounds-part-1-intro/ From 472069995ef3e6c3a81a99eca5ab645eb5c25541 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 21:40:58 -0400 Subject: [PATCH 06/19] correct funding comments --- text/0000-async-project-goal-2024h2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 6203904d4dd..ab3807f35b2 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -198,12 +198,12 @@ Here is a detailed list of the work to be done and who is expected to do it. Thi | ↳ ~~implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ author RFC | [nikomatsakis][] or [compiler-errors][] | ![Funded][] | | ↳ approve RFC | ![Team][] [Lang] | ![Not funded][] | -| ↳ stabilization | [compiler-errors][] | ![Not funded][] | +| ↳ stabilization | [compiler-errors][] | ![Funded][] | | resolve the ["send bound"][sb] problem | | ![Funded][] | | ↳ ~~RTN implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ ~~RTN RFC~~ | [nikomatsakis][] | ![Complete][] | | ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | ![Not funded][] | -| ↳ stabilization | [compiler-errors][] | ![Not funded][] | +| ↳ stabilization | [compiler-errors][] | ![Funded][] | | stabilize trait for async iteration | | ![Funded][] | | ↳ author RFC | [eholk][] | ![Funded][] | | ↳ approve RFC | ![Team][] [Libs-API] | ![Funded][] | From 15a2a8cc9043083974c65dc5a3c6d9b9ef6476cc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 12 Jun 2024 21:41:39 -0400 Subject: [PATCH 07/19] cleanup funding status --- text/0000-async-project-goal-2024h2.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index ab3807f35b2..a781ca8816e 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -197,20 +197,20 @@ Here is a detailed list of the work to be done and who is expected to do it. Thi | stabilize async closures | | ![Funded][] | | ↳ ~~implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ author RFC | [nikomatsakis][] or [compiler-errors][] | ![Funded][] | -| ↳ approve RFC | ![Team][] [Lang] | ![Not funded][] | -| ↳ stabilization | [compiler-errors][] | ![Funded][] | +| ↳ approve RFC | ![Team][] [Lang] | | +| ↳ stabilization | [compiler-errors][] | ![Funded][] | | resolve the ["send bound"][sb] problem | | ![Funded][] | | ↳ ~~RTN implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ ~~RTN RFC~~ | [nikomatsakis][] | ![Complete][] | -| ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | ![Not funded][] | -| ↳ stabilization | [compiler-errors][] | ![Funded][] | +| ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | | +| ↳ stabilization | [compiler-errors][] | ![Funded][] | | stabilize trait for async iteration | | ![Funded][] | | ↳ author RFC | [eholk][] | ![Funded][] | | ↳ approve RFC | ![Team][] [Libs-API] | ![Funded][] | | ↳ implementation | [eholk][] | ![Funded][] | | author draft RFC for async vision | | ![Funded][] | | ↳ author RFC | [tmandry][] | ![Funded][] | -| ↳ approve RFC | ![Team][] [Lang], [Libs-API] | ![Not approved][] | +| ↳ approve RFC | ![Team][] [Lang], [Libs-API] | | | complete async drop experiments | | | | ↳ ~~author MCP~~ | ~~[petrochenkov][]~~ | ![Complete][] | | ↳ ~~approve MCP~~ | ~~[Compiler]~~ | ![Complete][] | From 570dbaf003d17449c853ce7ca7855e5e679314f6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 21 Jun 2024 08:17:27 -0400 Subject: [PATCH 08/19] Apply suggestions from code review Co-authored-by: Tyler Mandry --- text/0000-async-project-goal-2024h2.md | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index a781ca8816e..17daf5d9e40 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -32,11 +32,15 @@ Async Rust is the most common Rust application area according to our [2023 Rust * **Rust scales up**. Async Rust reduces cost for large dataplanes because a single server can serve high load without significantly increasing tail latency. * **Rust scales down.** Async Rust can be run without requiring a garbage collector or [even an operating system][embassy], making it a great fit for embedded systems. -* **Rust is reliable.** Networked services run 24/7, so Rust's "if it compiles, it works" mantra means unexpected failures and, in turn, fewer pages in the middle of the night. +* **Rust is reliable.** Networked services run 24/7, so Rust's "if it compiles, it works" mantra means fewer unexpected failures and, in turn, fewer pages in the middle of the night. Despite async Rust's popularity, using async I/O makes Rust significantly harder to use. As one Rust user memorably put it, "Async Rust is Rust on hard mode." Several years back the async working group collected a number of ["status quo" stories](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo.html) as part of authoring an async vision doc. These stories reveal a number of characteristic challenges: -* Common language features like ~~[traits](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_needs_async_in_traits.html)~~ (they [do now][afitblog], though gaps remain), closures, and [drop](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_finds_database_drops_hard.html) do not support async, meaning that [users cannot write Rust code in the way they are accustomed to](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_plays_with_async.html?highlight=closure#the-story). In many cases there are workarounds or crates that can close the gap, but users have to learn about and find those crates. +* Common language features do not support async, meaning that [users cannot write Rust code in the way they are accustomed to](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_plays_with_async.html?highlight=closure#the-story): + * [x] ~~[traits](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_needs_async_in_traits.html)~~ (they [do now][afitblog], though gaps remain) + * [ ] closures + * [ ] [drop](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_finds_database_drops_hard.html) + In many cases there are workarounds or crates that can close the gap, but users have to learn about and find those crates. * Common async idioms have "sharp edges" that lead to unexpected failures, forcing users to manage [cancellation safety](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_gets_burned_by_select.html), subtle [deadlocks](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/aws_engineer/solving_a_deadlock.html) and other failure modes for [buffered streams](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_battles_buffered_streams.html). See also tmandry's blog post on [Making async Rust reliable](https://tmandry.gitlab.io/blog/posts/making-async-reliable/)). * Using async today requires users to select a runtime which provides many of the core primitives. Selecting a runtime as a user [can be stressful](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_makes_their_first_steps_into_async.html#the-wrong-time-for-big-decisions), as the [decision once made is hard to reverse](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_wishes_for_easy_runtime_switch.html). Moreover, in an attempt to avoid "picking favories", the project has not endorsed a particular runtime, making it [harder to write new user documentation](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/niklaus_wants_to_share_knowledge.html). Libaries meanwhile [cannot easily be made interoperable across runtimes](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_writes_a_runtime_agnostic_lib.html) and so are often written against the API of a particular runtime; even when libraries can be retargeted, it is difficult to do things like run their test suites to test compatibility. [Mixing and matching libraries can cause surprising failures.](https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/alan_started_trusting_the_rust_compiler_but_then_async.html) @@ -46,7 +50,7 @@ Despite async Rust's popularity, using async I/O makes Rust significantly harder ### First focus: language parity, interop traits -Based on the above analysis, the Rust org has been focused on driving async/sync language parity, especially in those areas that block the development of a rich ecosystem. The biggest progress took place in [Dec 2023][afitblog], when async fn in traits and return position impl trait in trait were stabilizd. Other work includes authoring the async vision doc, stabilizing helpers like [`std::future::poll_fn`](https://doc.rust-lang.org/std/future/fn.poll_fn.html)), and polishing and improving async error messages. +Based on the above analysis, the Rust org has been focused on driving async/sync language parity, especially in those areas that block the development of a rich ecosystem. The biggest progress took place in [Dec 2023][afitblog], when async fn in traits and return position impl trait in trait were stabilized. Other work includes documenting async usability challenges in the original async vision doc, stabilizing helpers like [`std::future::poll_fn`](https://doc.rust-lang.org/std/future/fn.poll_fn.html), and polishing and improving async error messages. ### Lack of internal alignment within the Rust org about the direction for async @@ -64,7 +68,7 @@ In the second half of 2024 we are planning on the following work items: ### Stabilize async closures -Building ergonomic APIs in async is often blocked by the lack of *async closures*. Async combinator-like APIs today typically make use an ordinary Rust closure that returns a future, such as the `filter` API from [`StreamExt`](https://docs.rs/futures/latest/futures/prelude/stream/trait.StreamExt.html#method.filter): +Building ergonomic APIs in async is often blocked by the lack of *async closures*. Async combinator-like APIs today typically make use of an ordinary Rust closure that returns a future, such as the `filter` API from [`StreamExt`](https://docs.rs/futures/latest/futures/prelude/stream/trait.StreamExt.html#method.filter): ```rust fn filter(self, f: F) -> Filter @@ -121,17 +125,17 @@ There has been extensive discussion about the best form of the trait for async i ### Resolve the ["send bound"][sb] problem -Although async functions in traits were stabilized, there is currently no way to write a generic function that requires only impls where the returned futures are `Send`. This blocks the use of async function in traits in some core ecosystem crates, such as [tower](https://crates.io/crates/tower), which want to work across all kinds of async executors. This problem is called the ["send bound"][sb] problem and there has been extensive discussion of the various ways to solve it. [RFC #3654][] has been opened proposing one solution and describing why that path is preferred. Our goal for the year is to adopt *some* solution on stable. +Although async functions in traits were stabilized, there is currently no way to write a generic function that requires impls where the returned futures are `Send`. This blocks the use of async function in traits in some core ecosystem crates, such as [tower](https://crates.io/crates/tower), which want to work across all kinds of async executors. This problem is called the ["send bound"][sb] problem and there has been extensive discussion of the various ways to solve it. [RFC #3654][] has been opened proposing one solution and describing why that path is preferred. Our goal for the year is to adopt *some* solution on stable. [RFC #3654]: https://github.com/rust-lang/rfcs/pull/3654 ### Author draft RFC for async vision -We plan to revise the [Async Vision Doc][AVD] and restructure it as a draft RFC, most likely to be approved by the [Lang][] and [Libs-API][] teams (we do not necessarily expect that RFC to be accepted by end of year). Our observation is that the previous version of the async vision doc, which was never RFC'd, never attained the legitimacy of being the "plan of record". In addition, a number of things have changed in the intervening years (for example, async functions in traits are now stable) and we are in a position to identify clearer next steps. The +We plan to revise the [Async Vision Doc][AVD] and restructure it as a draft RFC, most likely to be approved by the [Lang][] and [Libs-API][] teams (we do not necessarily expect that RFC to be accepted by end of year). Our observation is that the previous version of the async vision doc, which was never RFC'd, never attained the legitimacy of being the "plan of record". In addition, a number of things have changed in the intervening years (for example, async functions in traits are now stable) and we are in a position to identify clearer next steps. [AVD]: https://rust-lang.github.io/wg-async/vision.html -This RFC will lay out a "plan of attack" for async, including both obvious good things (similar to [async closures][]) but also "known unknowns" and ways to resolve them. Areas the RFC is expected to cover are as follows: +This RFC will lay out a "plan of attack" for async, including both obvious good things (similar to [async closures](#stabilize-async-closures)) but also "known unknowns" and ways to resolve them. Areas the RFC is expected to cover are as follows: [Making Async Rust Reliable]: https://tmandry.gitlab.io/blog/posts/making-async-reliable/ @@ -140,7 +144,7 @@ This RFC will lay out a "plan of attack" for async, including both obvious good * Common idioms contain footguns that cause unexpected failures (see e.g., Tyler's blog post [Making Async Rust Reliable][]) * Low-level performance hurdles, such as large future sizes and downsides of the poll model * Fragmentation between runtimes -* Design axioms to pursue for async (see e.g. axioms proposed) +* Design axioms to pursue for async (see e.g. axioms proposed below) * Goals, some variant of * Free of accidental complexity * Easy to get started @@ -165,7 +169,7 @@ This RFC will lay out a "plan of attack" for async, including both obvious good ### Complete async drop experiments -Authors of async code frequently need to call async functions as part of resource cleanup. Because Rust today only supports synchronous destructors, this cleanup must take place using alternative mechanisms, forcing a divergence between sync Rust (which uses destructors to arrange cleanup) and async Rust. [MCP 727][] proposed a series of experiments aimed at supporting async drop in the compiler. We would like to continue and complete those experiments. These experiments are aimed at defining how support for async drop will be implemented in the compiler and some possible ways that we could modify the type system to support it (in particular, one key question is how to prevent types that whose drop is async from being dropped in sync code). +Authors of async code frequently need to call async functions as part of resource cleanup. Because Rust today only supports synchronous destructors, this cleanup must take place using alternative mechanisms, forcing a divergence between sync Rust (which uses destructors to arrange cleanup) and async Rust. [MCP 727][] proposed a series of experiments aimed at supporting async drop in the compiler. We would like to continue and complete those experiments. These experiments are aimed at defining how support for async drop will be implemented in the compiler and some possible ways that we could modify the type system to support it (in particular, one key question is how to prevent types whose drop is async from being dropped in sync code). ## The "shiny future" we are working towards @@ -178,8 +182,8 @@ Our eventual goal is to provide Rust users building on async with # Design axiom -* **We lay the foundations for a thriving ecosystem.** The role of the Rust org is to deelop the rudiments that support an interoperable and thriving async crates.io ecosystem. -* **Uphold sync's Rust bar for reliability.** Sync Rust famously delivers on the general feeling of "if it compiles, in works" -- async Rust should do the same. +* **We lay the foundations for a thriving ecosystem.** The role of the Rust org is to develop the rudiments that support an interoperable and thriving async crates.io ecosystem. +* **Uphold sync Rust's bar for reliability.** Sync Rust famously delivers on the general feeling of "if it compiles, in works" -- async Rust should do the same. * **When in doubt, zero-cost is our compass.** Many of Rust's biggest users are choosing it becase they know it can deliver the same performnace (or better) than C. If we adopt abstractions that add overhead, we are compromising that core strength. As we build out our designs, we ensure that they don't introduce an "abstraction tax" for using them. * **From embedded to GUI to the cloud.** Async Rust covers a wide variety of use cases and we aim to make designs that can span those differing constraints with ease. * **Consistent, incremental progress.** People are building async Rust systems *today* -- we need to ship incremental improvements while also steering towards the overall outcome we want. @@ -253,7 +257,7 @@ Async fn in traits do not currently support native dynamic dispatch. We have exp There has been extensive discussion about the best design for the "Stream" or "async iter" trait and we judge that the design space is well understood. We would like to unblock generator syntax in 2025 which will require some form of trait. -The majority of the debate about the trait has been on the topic of whether to base the trait on a `poll_next` function, as we do today, or to try and make the trait use `async fn next`, making it more anaologous with the `Iterator` trait (and potentially even making it be two versions of a single trait). We will definitely explore forwards compatibility questions as part of this discussion. nikomatsakis for example still wants to explore maybe-async-like designs, especially for combinator APIs like `map`. However, we also refer to the design axiom that that "when in doubt, zero-cost is our compass" -- we believe we should be able to stabilize a trait that does the low-level details right, and then design higher level APIs atop that. +The majority of the debate about the trait has been on the topic of whether to base the trait on a `poll_next` function, as we do today, or to try and make the trait use `async fn next`, making it more anaologous with the `Iterator` trait (and potentially even making it be two versions of a single trait). We will definitely explore forwards compatibility questions as part of this discussion. nikomatsakis for example still wants to explore maybe-async-like designs, especially for combinator APIs like `map`. However, we also refer to the design axiom that "when in doubt, zero-cost is our compass" -- we believe we should be able to stabilize a trait that does the low-level details right, and then design higher level APIs atop that. ## Why work on a revised async vision doc? Don't we already have one? From 4da91ace3b5ba98e78a8140de0f9cceea4314474 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 21 Jun 2024 08:32:36 -0400 Subject: [PATCH 09/19] reorder axioms, remove duplication --- text/0000-async-project-goal-2024h2.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 17daf5d9e40..10538586db1 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -144,13 +144,8 @@ This RFC will lay out a "plan of attack" for async, including both obvious good * Common idioms contain footguns that cause unexpected failures (see e.g., Tyler's blog post [Making Async Rust Reliable][]) * Low-level performance hurdles, such as large future sizes and downsides of the poll model * Fragmentation between runtimes -* Design axioms to pursue for async (see e.g. axioms proposed below) -* Goals, some variant of - * Free of accidental complexity - * Easy to get started - * Easy to pick executor and integrate with other systems (e.g., mobile runtimes, company-specific threadpools, etc) - * Moderately easy to adapt to "extreme" embedded environments - * Good performance by default, peak performance with tuning +* Design axioms, an expanded version of the [axioms](#design-axiom) described here +* Goals, an expanded version of the [shiny future](#the-shiny-future-we-are-working-towards) described here * Key unknowns in terms of how to achieve the above goals, for example * how to replace footgun-prone APIs with more reliable alternatives: * buffered-streams, cancellation (esp. due to use of select) @@ -176,14 +171,15 @@ Authors of async code frequently need to call async functions as part of resourc Our eventual goal is to provide Rust users building on async with * the same core language capabilities as sync Rust (async traits with dyn dispatch, async closures, async drop, etc); -* reliable and standardized abstractions for async control flow (streams of data, error recovery, concurrent execution); +* reliable and standardized abstractions for async control flow (streams of data, error recovery, concurrent execution), free of accidental complexity; * an easy "getting started" experience that builds on a rich ecosystem; +* good performance by default, peak performance with tuning; * the ability to easily adopt custom runtimes when needed for particular environments, language interop, or specific business needs. # Design axiom -* **We lay the foundations for a thriving ecosystem.** The role of the Rust org is to develop the rudiments that support an interoperable and thriving async crates.io ecosystem. * **Uphold sync Rust's bar for reliability.** Sync Rust famously delivers on the general feeling of "if it compiles, in works" -- async Rust should do the same. +* **We lay the foundations for a thriving ecosystem.** The role of the Rust org is to develop the rudiments that support an interoperable and thriving async crates.io ecosystem. * **When in doubt, zero-cost is our compass.** Many of Rust's biggest users are choosing it becase they know it can deliver the same performnace (or better) than C. If we adopt abstractions that add overhead, we are compromising that core strength. As we build out our designs, we ensure that they don't introduce an "abstraction tax" for using them. * **From embedded to GUI to the cloud.** Async Rust covers a wide variety of use cases and we aim to make designs that can span those differing constraints with ease. * **Consistent, incremental progress.** People are building async Rust systems *today* -- we need to ship incremental improvements while also steering towards the overall outcome we want. From b4ef2362303afa2fe4201c4e077a18afd8e99d0b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 21 Jun 2024 08:34:08 -0400 Subject: [PATCH 10/19] clarify expectations --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 10538586db1..da8f44a634f 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -261,7 +261,7 @@ The existing doc was authored some time back and is in need of an update. Moreov ## What about "maybe async", effect systems, and keyword generics? -Keyword generics is an ambitious initiative to enable code that is "maybe async". It has generated significant controversy, with some people feeling it is necessary for Rust to scale and others judging it to be overly complex. We anticipate having more debate on this topic as part of drafting the async vision doc. +Keyword generics is an ambitious initiative to enable code that is "maybe async". It has generated significant controversy, with some people feeling it is necessary for Rust to scale and others judging it to be overly complex. We anticipate having more debate on this topic as part of drafting the async vision doc. We may not fully settle it, but we will better characterize the design space and key considerations. [tmandry]: https://github.com/tmandry [nikomatsakis]: https://github.com/nikomatsakis From bec231d8da45da68e1066b6b4c4f40d752322891 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 21 Jun 2024 08:35:59 -0400 Subject: [PATCH 11/19] remove redundant section --- text/0000-async-project-goal-2024h2.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index da8f44a634f..9b2f56e5ffe 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -232,13 +232,6 @@ Agreement from [Lang] and [Libs-API] to the items marked ![Team][] in the table Expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. -# Outputs and milestones - -Stabilized features for - -* async closures -* a ["send bound"][sb] solution, most likely [RTN][] - # Frequently asked questions ## Why focus on send bounds + async closures? From aa2dec5e4905efcdc66a41986b586cb3aea55957 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 21 Jun 2024 14:22:58 -0400 Subject: [PATCH 12/19] priority order --- text/0000-async-project-goal-2024h2.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 9b2f56e5ffe..d624e072013 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -58,14 +58,20 @@ Progress on async-related issues within the Rust org has been slowed due to lack ## The next few steps -In the second half of 2024 we are planning on the following work items: +In the second half of 2024 we are planning on the following work items. These items are ambitious and likely will not all get done. For that reason, they are prioritized, with higher priority items being listed first. -* [stabilize async closures](#stabilize-async-closures) * [resolve the "Send bound" problem](#stabilize-async-closures) +* [stabilize async closures](#stabilize-async-closures) * [stabilize trait for async iteration](#stabilize-trait-for-async-iteration) * [author draft RFC for async vision](#author-draft-rfc-for-async-vision) * [complete async drop experiments](#complete-async-drop-experiments) (currently unfunded) +### Resolve the ["send bound"][sb] problem + +Although async functions in traits were stabilized, there is currently no way to write a generic function that requires impls where the returned futures are `Send`. This blocks the use of async function in traits in some core ecosystem crates, such as [tower](https://crates.io/crates/tower), which want to work across all kinds of async executors. This problem is called the ["send bound"][sb] problem and there has been extensive discussion of the various ways to solve it. [RFC #3654][] has been opened proposing one solution and describing why that path is preferred. Our goal for the year is to adopt *some* solution on stable. + +[RFC #3654]: https://github.com/rust-lang/rfcs/pull/3654 + ### Stabilize async closures Building ergonomic APIs in async is often blocked by the lack of *async closures*. Async combinator-like APIs today typically make use of an ordinary Rust closure that returns a future, such as the `filter` API from [`StreamExt`](https://docs.rs/futures/latest/futures/prelude/stream/trait.StreamExt.html#method.filter): @@ -123,12 +129,6 @@ The details (syntax, precise semantics) will be determined via experimentation a There has been extensive discussion about the best form of the trait for async iteration (sometimes called `Stream`, sometimes `AsyncIter`, and now being called `AsyncGen`). We believe the design space has been sufficiently explored that it should be possible to author an RFC laying out the options and proposing a specific plan. -### Resolve the ["send bound"][sb] problem - -Although async functions in traits were stabilized, there is currently no way to write a generic function that requires impls where the returned futures are `Send`. This blocks the use of async function in traits in some core ecosystem crates, such as [tower](https://crates.io/crates/tower), which want to work across all kinds of async executors. This problem is called the ["send bound"][sb] problem and there has been extensive discussion of the various ways to solve it. [RFC #3654][] has been opened proposing one solution and describing why that path is preferred. Our goal for the year is to adopt *some* solution on stable. - -[RFC #3654]: https://github.com/rust-lang/rfcs/pull/3654 - ### Author draft RFC for async vision We plan to revise the [Async Vision Doc][AVD] and restructure it as a draft RFC, most likely to be approved by the [Lang][] and [Libs-API][] teams (we do not necessarily expect that RFC to be accepted by end of year). Our observation is that the previous version of the async vision doc, which was never RFC'd, never attained the legitimacy of being the "plan of record". In addition, a number of things have changed in the intervening years (for example, async functions in traits are now stable) and we are in a position to identify clearer next steps. @@ -194,16 +194,16 @@ Here is a detailed list of the work to be done and who is expected to do it. Thi | Subgoal | Owner(s) or team(s) | Status | | ---------------------------------------- | --------------------------------------- | ------------------- | | overall program management | [tmandry][], [nikomatsakis][] | ![Funded][] | -| stabilize async closures | | ![Funded][] | -| ↳ ~~implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | -| ↳ author RFC | [nikomatsakis][] or [compiler-errors][] | ![Funded][] | -| ↳ approve RFC | ![Team][] [Lang] | | -| ↳ stabilization | [compiler-errors][] | ![Funded][] | | resolve the ["send bound"][sb] problem | | ![Funded][] | | ↳ ~~RTN implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ ~~RTN RFC~~ | [nikomatsakis][] | ![Complete][] | | ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | | | ↳ stabilization | [compiler-errors][] | ![Funded][] | +| stabilize async closures | | ![Funded][] | +| ↳ ~~implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | +| ↳ author RFC | [nikomatsakis][] or [compiler-errors][] | ![Funded][] | +| ↳ approve RFC | ![Team][] [Lang] | | +| ↳ stabilization | [compiler-errors][] | ![Funded][] | | stabilize trait for async iteration | | ![Funded][] | | ↳ author RFC | [eholk][] | ![Funded][] | | ↳ approve RFC | ![Team][] [Libs-API] | ![Funded][] | From 08ef6b4d115a3a2a2a029b77829a9e7fb0fd65ca Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 22 Jun 2024 05:34:47 -0400 Subject: [PATCH 13/19] s/async vision doc/reorganize async wg/ also, clarify prioritization --- text/0000-async-project-goal-2024h2.md | 114 ++++++++++++------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index d624e072013..ed539a11a79 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -3,22 +3,25 @@ - RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) - Goal owners: [tmandry][], [nikomatsakis][] -- Goal teams: [Lang], [Libs-API] +- Goal teams: [Lang], [Libs-API], [Libs] # Summary [summary]: #summary This is a proposed flagship goal for 2024h2 covering **async Rust**. You can [read more about the project goal slate and its associated process here](https://rust-lang.github.io/rust-project-goals/2024h2/slate.html). This RFC is prepared using the project goal template, which differs from the typical RFC template. -The overall goal is **bringing the Async Rust experience closer to parity with sync Rust** via the following steps: +The overall goal is **bringing the Async Rust experience closer to parity with sync Rust**. We have identified three high-priority goals that we believe would do the most to improve async over the long term: -* stabilizing async closures, thus enabling richer, combinator APIs like sync Rust's [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html); * [resolving the "send bound problem"](#resolve-the-send-bound-problem), thus enabling foundational, generic traits like Tower's [`Service`]() trait; +* stabilizing async closures, thus enabling richer, combinator APIs like sync Rust's [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html); +* [reorganizing the async WG](#reorganize-the-async-wg), so the project can benefit from a group of async rust experts with deep knowledge of the space that can align around a shared vision; + +We have also identified two "stretch goals": + * [stabilizing a trait in libstd for async iteration](#stabilize-trait-for-async-iteration), thus enabling the ecosystem to build atop a stable foundation; -* [authoring a draft RFC for async vision](#author-draft-rfc-for-async-vision), thus aligning the project around a coherent vision; * [completing the async drop experiments](#complete-async-drop-experiments) proposed in [MCP 727][], laying the groundwork for resolving the the next major gap in language feature support. -Approving this goal implies agreement from the [Lang][] and [Libs-API][] team to the items marked as ![Team][] in the table of work items, along with potentially other design meetings as needed. The expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. +Approving this goal implies agreement from the [Lang][], [Libs][], and [Libs-API][] teams to the items marked as ![Team][] in the table of work items, along with potentially other design meetings as needed. # Motivation @@ -52,18 +55,21 @@ Despite async Rust's popularity, using async I/O makes Rust significantly harder Based on the above analysis, the Rust org has been focused on driving async/sync language parity, especially in those areas that block the development of a rich ecosystem. The biggest progress took place in [Dec 2023][afitblog], when async fn in traits and return position impl trait in trait were stabilized. Other work includes documenting async usability challenges in the original async vision doc, stabilizing helpers like [`std::future::poll_fn`](https://doc.rust-lang.org/std/future/fn.poll_fn.html), and polishing and improving async error messages. -### Lack of internal alignment within the Rust org about the direction for async +### The need for an aligned, high judgment group of async experts -Progress on async-related issues within the Rust org has been slowed due to lack of coherence around a vision and clear steps. Discussion gets stuck not only on technical details but also on what problems to be resolving first. The lack of a centrally agreed upon vision has also made it hard for general purpose teams such as [Lang][] or [Libs-API][] to decide how to respond to requests to e.g. stabilize particular async-related constructs, as they lack a means to judge whether stabilizing any particular construct is really the right step forward and whether it meets its design needs. +Progress on async-related issues within the Rust org has been slowed due to lack of coherence around a vision and clear steps. General purpose teams such as [Lang][] and [Libs-API][] have a hard time determining how to respond to, e.g., particular async stabilization requests, as they lack a means to judge whether any given decision is really the right step forward. Theoretically, the async working group could play this role, but it has not really been structured with this purpose in mind. For example, the [criteria for membership](https://rust-lang.github.io/wg-async/CHARTER.html#membership-requirements) is loose and the group would benefit from more representation from async ecosystem projects. This is an example of a larger piece of Rust "organizational debt", where the term "working group" has been used for many different purposes over the years. ## The next few steps -In the second half of 2024 we are planning on the following work items. These items are ambitious and likely will not all get done. For that reason, they are prioritized, with higher priority items being listed first. +In the second half of 2024 we are planning on the following work items. The following three items are what we consider to be the highest priority, as they do the most to lay a foundation for future progress (and they themselves are listed in priority order): + +* [resolve the "Send bound" problem](#stabilize-async-closures), which blocks the widespread usage of async functions in traits; +* [reorganize the async WG](#reorganize-the-async-wg), so that we can be better aligned and move more swiftly from here out; +* [stabilize async closures](#stabilize-async-closures), allowing for a much wider variety of async related APIs (async closures are implemented on nightly). + +We have also identified two "stretch goals" that we believe could be completed: -* [resolve the "Send bound" problem](#stabilize-async-closures) -* [stabilize async closures](#stabilize-async-closures) * [stabilize trait for async iteration](#stabilize-trait-for-async-iteration) -* [author draft RFC for async vision](#author-draft-rfc-for-async-vision) * [complete async drop experiments](#complete-async-drop-experiments) (currently unfunded) ### Resolve the ["send bound"][sb] problem @@ -72,6 +78,18 @@ Although async functions in traits were stabilized, there is currently no way to [RFC #3654]: https://github.com/rust-lang/rfcs/pull/3654 +### Reorganize the Async WG + +We plan to reorganize the async working group into a structure that will better serve the projects needs, especially when it comes to [aligning around a clear async vision](#the-need-for-an-aligned-high-judgment-group-of-async-experts). In so doing, we will help "launch" the async working group out from the [launchpad](https://forge.rust-lang.org/governance/council.html#the-launching-pad-top-level-team) umbrella team and into a more permanent structure. + +Despite its limitations, the async working group serves several important functions for async Rust that need to continue: + +* It provides a forum for discussion around async-related topics, including the `#async-wg` zulip stream as well as regular sync meetings. These forums don't necessarily get participation by the full set of voices that we would like, however. +* It owns async-related repositories, such as the sources for the [async Rust book](https://rust-lang.github.io/async-book/) (in dire need of improvement), [arewewebyet](https://www.arewewebyet.org/), the [futures-rs](https://rust-lang.github.io/futures-rs/) crate. Maintenance of these sites has varied though and often been done by a few individuals acting largely independently. +* It advises the more general teams (typically [Lang][] and [Libs-API][]) on async-related matters. The authoring of the (somewhat dated) [async vision doc](https://rust-lang.github.io/wg-async/vision/) took place under the auspices of the working group, for example. However, the group lacks decision making power and doesn't have a strong incentive to truly "coallesce" behind a shared vision, so it remains more a "set of individual voices" that can still leave the general purpose teams without clear guidance. + +We plan to propose one or more permanent teams to meet these same set of needs. The expectation is that these will be subteams under the [Lang] and [Libs] top-level teams. + ### Stabilize async closures Building ergonomic APIs in async is often blocked by the lack of *async closures*. Async combinator-like APIs today typically make use of an ordinary Rust closure that returns a future, such as the `filter` API from [`StreamExt`](https://docs.rs/futures/latest/futures/prelude/stream/trait.StreamExt.html#method.filter): @@ -127,43 +145,14 @@ The details (syntax, precise semantics) will be determined via experimentation a ### Stabilize trait for async iteration -There has been extensive discussion about the best form of the trait for async iteration (sometimes called `Stream`, sometimes `AsyncIter`, and now being called `AsyncGen`). We believe the design space has been sufficiently explored that it should be possible to author an RFC laying out the options and proposing a specific plan. +![Stretch Goal](https://img.shields.io/badge/Stretch%20Goal-red) -### Author draft RFC for async vision - -We plan to revise the [Async Vision Doc][AVD] and restructure it as a draft RFC, most likely to be approved by the [Lang][] and [Libs-API][] teams (we do not necessarily expect that RFC to be accepted by end of year). Our observation is that the previous version of the async vision doc, which was never RFC'd, never attained the legitimacy of being the "plan of record". In addition, a number of things have changed in the intervening years (for example, async functions in traits are now stable) and we are in a position to identify clearer next steps. - -[AVD]: https://rust-lang.github.io/wg-async/vision.html - -This RFC will lay out a "plan of attack" for async, including both obvious good things (similar to [async closures](#stabilize-async-closures)) but also "known unknowns" and ways to resolve them. Areas the RFC is expected to cover are as follows: - -[Making Async Rust Reliable]: https://tmandry.gitlab.io/blog/posts/making-async-reliable/ - -* Status quo, covering biggest challenges - * Lack of strong learning material - * Common idioms contain footguns that cause unexpected failures (see e.g., Tyler's blog post [Making Async Rust Reliable][]) - * Low-level performance hurdles, such as large future sizes and downsides of the poll model - * Fragmentation between runtimes -* Design axioms, an expanded version of the [axioms](#design-axiom) described here -* Goals, an expanded version of the [shiny future](#the-shiny-future-we-are-working-towards) described here -* Key unknowns in terms of how to achieve the above goals, for example - * how to replace footgun-prone APIs with more reliable alternatives: - * buffered-streams, cancellation (esp. due to use of select) - * patterns to express - * merged streams -- processing one stream of data with occasional control events - * task parallelism - * cleanup and teardown - * ordered destruction - * how should async drop work (`?Leak` vs `?Drop` vs whatever): - * how to prevent async drop from occuring in sync contexts? - * what does runtime interface look like? - * Can/should we be generic over runtime -* Strategy for how to get where we are going - * What problems to attack first - * How to reduce or find solutions to the above unknowns +There has been extensive discussion about the best form of the trait for async iteration (sometimes called `Stream`, sometimes `AsyncIter`, and now being called `AsyncGen`). We believe the design space has been sufficiently explored that it should be possible to author an RFC laying out the options and proposing a specific plan. ### Complete async drop experiments +![Not funded][] + Authors of async code frequently need to call async functions as part of resource cleanup. Because Rust today only supports synchronous destructors, this cleanup must take place using alternative mechanisms, forcing a divergence between sync Rust (which uses destructors to arrange cleanup) and async Rust. [MCP 727][] proposed a series of experiments aimed at supporting async drop in the compiler. We would like to continue and complete those experiments. These experiments are aimed at defining how support for async drop will be implemented in the compiler and some possible ways that we could modify the type system to support it (in particular, one key question is how to prevent types whose drop is async from being dropped in sync code). ## The "shiny future" we are working towards @@ -189,28 +178,29 @@ Our eventual goal is to provide Rust users building on async with Here is a detailed list of the work to be done and who is expected to do it. This table includes the work to be done by owners and the work to be done by Rust teams (subject to approval by the team in an RFC/FCP). The overall owners of the async effort (and authors of this goal document) are [tmandry][] and [nikomatsakis][]. We have identified owners for subitems below; these may change over time. * The ![Funded][] badge indicates that the owner has committed and work will be funded by their employer or other sources. +* The ![Not founded][] badge indictes that there is a willing owner but they need funding to pursue the goal. Depending on the owner's individual circumstances, this could be support/authorizaiton from their employer, grants, or contracting. * The ![Team][] badge indicates a requirement where Team support is needed. | Subgoal | Owner(s) or team(s) | Status | | ---------------------------------------- | --------------------------------------- | ------------------- | | overall program management | [tmandry][], [nikomatsakis][] | ![Funded][] | -| resolve the ["send bound"][sb] problem | | ![Funded][] | +| resolve the ["send bound"][sb] problem | | | | ↳ ~~RTN implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ ~~RTN RFC~~ | [nikomatsakis][] | ![Complete][] | -| ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | | +| ↳ approve RTN RFC or provide alternative | ![Team][] [Lang] | (in FCP) | | ↳ stabilization | [compiler-errors][] | ![Funded][] | -| stabilize async closures | | ![Funded][] | +| reorganize the async WG | | | +| ↳ author proposal | [tmandry][], [nikomatsakis][] | ![Funded][] | +| ↳ approve changes to team structure | ![Team][] [Libs], [Lang] | | +| stabilize async closures | | | | ↳ ~~implementation~~ | ~~[compiler-errors][]~~ | ![Complete][] | | ↳ author RFC | [nikomatsakis][] or [compiler-errors][] | ![Funded][] | | ↳ approve RFC | ![Team][] [Lang] | | | ↳ stabilization | [compiler-errors][] | ![Funded][] | -| stabilize trait for async iteration | | ![Funded][] | +| stabilize trait for async iteration | | | | ↳ author RFC | [eholk][] | ![Funded][] | | ↳ approve RFC | ![Team][] [Libs-API] | ![Funded][] | | ↳ implementation | [eholk][] | ![Funded][] | -| author draft RFC for async vision | | ![Funded][] | -| ↳ author RFC | [tmandry][] | ![Funded][] | -| ↳ approve RFC | ![Team][] [Lang], [Libs-API] | | | complete async drop experiments | | | | ↳ ~~author MCP~~ | ~~[petrochenkov][]~~ | ![Complete][] | | ↳ ~~approve MCP~~ | ~~[Compiler]~~ | ![Complete][] | @@ -225,15 +215,24 @@ Here is a detailed list of the work to be done and who is expected to do it. Thi [Complete]: https://img.shields.io/badge/Complete-green [TBD]: https://img.shields.io/badge/TBD-red - ## Support needed from the project -Agreement from [Lang] and [Libs-API] to the items marked ![Team][] in the table above. Potentially other design meetings as needed. +Agreement from [Lang][], [Libs][] [Libs-API][] to prioritize the items marked ![Team][] in the table above. -Expectation is that 3-4 design meetings will be needed from lang over the course of H2 and 1-2 from libs API. Reviewing the async vision doc is expected to be the biggest requirement. +The expectation is that + +* async closures will occupy 2 design meetings from lang during H2 +* async iteration will occupy 2 design meetings from lang during H2 and likely 1-2 from libs API +* misc matters will occupy 1 design meeting from lang during H2 + +for a total of 4-5 meetings from lang and 1-2 from libs API. # Frequently asked questions +## Can we really do all of this in 6 months? + +This is an ambitious agenda, no doubt. We believe it is possible if the teams are behind us, but things always take longer than you think. We have made sure to document the "priority order" of items for this reason. We intend to focus our attention first and foremost on the high priority items. + ## Why focus on send bounds + async closures? These are the two features that together block the authoring of traits for a number of common interop purposes. Send bounds are needed for generic traits like the `Service` trait. Async closures are needed for rich combinator APIs like iterators. @@ -248,13 +247,13 @@ There has been extensive discussion about the best design for the "Stream" or "a The majority of the debate about the trait has been on the topic of whether to base the trait on a `poll_next` function, as we do today, or to try and make the trait use `async fn next`, making it more anaologous with the `Iterator` trait (and potentially even making it be two versions of a single trait). We will definitely explore forwards compatibility questions as part of this discussion. nikomatsakis for example still wants to explore maybe-async-like designs, especially for combinator APIs like `map`. However, we also refer to the design axiom that "when in doubt, zero-cost is our compass" -- we believe we should be able to stabilize a trait that does the low-level details right, and then design higher level APIs atop that. -## Why work on a revised async vision doc? Don't we already have one? +## Why do you say that we lack a vision, don't we have an [async vision doc][avd]? -The existing doc was authored some time back and is in need of an update. Moreover, the original doc was never RFC'd and we have found that it lacks a certain measure of "authority" as a result. We would like to drive stronger alignment on the path forward so that we can focus more on execution. +Yes, we do, and the [existing document][avd] has been very helpful in understanding the space. Moreover, that document was never RFC'd and we have found that it lacks a certain measure of "authority" as a result. We would like to drive stronger alignment on the path forward so that we can focus more on execution. But doing that is blocked on having a more effective async working group structure (hence the goal to [reorganize the async WG](#reorganize-the-async-wg)). ## What about "maybe async", effect systems, and keyword generics? -Keyword generics is an ambitious initiative to enable code that is "maybe async". It has generated significant controversy, with some people feeling it is necessary for Rust to scale and others judging it to be overly complex. We anticipate having more debate on this topic as part of drafting the async vision doc. We may not fully settle it, but we will better characterize the design space and key considerations. +Keyword generics is an ambitious initiative to enable code that is "maybe async". It has generated significant controversy, with some people feeling it is necessary for Rust to scale and others judging it to be overly complex. One of the reasons to [reorganize the async WG](#reorganize-the-async-wg) is to help us come to a consensus around this point (though this topic is broader than async). [tmandry]: https://github.com/tmandry [nikomatsakis]: https://github.com/nikomatsakis @@ -264,5 +263,6 @@ Keyword generics is an ambitious initiative to enable code that is "maybe async" [Team]: https://img.shields.io/badge/Team%20ask-red [MCP 727]: https://github.com/rust-lang/compiler-team/issues/727 [Lang]: https://www.rust-lang.org/governance/teams/lang +[Libs]: https://www.rust-lang.org/governance/teams/library [Libs-API]: https://www.rust-lang.org/governance/teams/library#team-libs-api [sb]: https://smallcultfollowing.com/babysteps/blog/2023/02/01/async-trait-send-bounds-part-1-intro/ From 5f3ce9052ae6043ef1d8ca5f986ababe9a888d9e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 22 Jun 2024 05:40:25 -0400 Subject: [PATCH 14/19] s/in/if/, typo --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index ed539a11a79..8da6d1727bd 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -167,7 +167,7 @@ Our eventual goal is to provide Rust users building on async with # Design axiom -* **Uphold sync Rust's bar for reliability.** Sync Rust famously delivers on the general feeling of "if it compiles, in works" -- async Rust should do the same. +* **Uphold sync Rust's bar for reliability.** Sync Rust famously delivers on the general feeling of "if it compiles, it works" -- async Rust should do the same. * **We lay the foundations for a thriving ecosystem.** The role of the Rust org is to develop the rudiments that support an interoperable and thriving async crates.io ecosystem. * **When in doubt, zero-cost is our compass.** Many of Rust's biggest users are choosing it becase they know it can deliver the same performnace (or better) than C. If we adopt abstractions that add overhead, we are compromising that core strength. As we build out our designs, we ensure that they don't introduce an "abstraction tax" for using them. * **From embedded to GUI to the cloud.** Async Rust covers a wide variety of use cases and we aim to make designs that can span those differing constraints with ease. From 238c2b2bbfc47b0bc2a1e51e091e9cf81c676265 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 22 Jun 2024 05:41:21 -0400 Subject: [PATCH 15/19] add missing link --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 8da6d1727bd..4d9f3ad2697 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -13,7 +13,7 @@ This is a proposed flagship goal for 2024h2 covering **async Rust**. You can [re The overall goal is **bringing the Async Rust experience closer to parity with sync Rust**. We have identified three high-priority goals that we believe would do the most to improve async over the long term: * [resolving the "send bound problem"](#resolve-the-send-bound-problem), thus enabling foundational, generic traits like Tower's [`Service`]() trait; -* stabilizing async closures, thus enabling richer, combinator APIs like sync Rust's [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html); +* [stabilizing async closures](#stabilize-async-closures), thus enabling richer, combinator APIs like sync Rust's [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html); * [reorganizing the async WG](#reorganize-the-async-wg), so the project can benefit from a group of async rust experts with deep knowledge of the space that can align around a shared vision; We have also identified two "stretch goals": From 872a3ef09eae95c5e34ca463d96551d4d0e722bc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 22 Jun 2024 05:42:21 -0400 Subject: [PATCH 16/19] missing "and" --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 4d9f3ad2697..60a1970d130 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -85,7 +85,7 @@ We plan to reorganize the async working group into a structure that will better Despite its limitations, the async working group serves several important functions for async Rust that need to continue: * It provides a forum for discussion around async-related topics, including the `#async-wg` zulip stream as well as regular sync meetings. These forums don't necessarily get participation by the full set of voices that we would like, however. -* It owns async-related repositories, such as the sources for the [async Rust book](https://rust-lang.github.io/async-book/) (in dire need of improvement), [arewewebyet](https://www.arewewebyet.org/), the [futures-rs](https://rust-lang.github.io/futures-rs/) crate. Maintenance of these sites has varied though and often been done by a few individuals acting largely independently. +* It owns async-related repositories, such as the sources for the [async Rust book](https://rust-lang.github.io/async-book/) (in dire need of improvement), [arewewebyet](https://www.arewewebyet.org/), and the [futures-rs](https://rust-lang.github.io/futures-rs/) crate. Maintenance of these sites has varied though and often been done by a few individuals acting largely independently. * It advises the more general teams (typically [Lang][] and [Libs-API][]) on async-related matters. The authoring of the (somewhat dated) [async vision doc](https://rust-lang.github.io/wg-async/vision/) took place under the auspices of the working group, for example. However, the group lacks decision making power and doesn't have a strong incentive to truly "coallesce" behind a shared vision, so it remains more a "set of individual voices" that can still leave the general purpose teams without clear guidance. We plan to propose one or more permanent teams to meet these same set of needs. The expectation is that these will be subteams under the [Lang] and [Libs] top-level teams. From cd844c7ebc74b907dcbc81915d4a647d5024c05b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 22 Jun 2024 05:43:32 -0400 Subject: [PATCH 17/19] reword --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 60a1970d130..ed2460572c1 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -86,7 +86,7 @@ Despite its limitations, the async working group serves several important functi * It provides a forum for discussion around async-related topics, including the `#async-wg` zulip stream as well as regular sync meetings. These forums don't necessarily get participation by the full set of voices that we would like, however. * It owns async-related repositories, such as the sources for the [async Rust book](https://rust-lang.github.io/async-book/) (in dire need of improvement), [arewewebyet](https://www.arewewebyet.org/), and the [futures-rs](https://rust-lang.github.io/futures-rs/) crate. Maintenance of these sites has varied though and often been done by a few individuals acting largely independently. -* It advises the more general teams (typically [Lang][] and [Libs-API][]) on async-related matters. The authoring of the (somewhat dated) [async vision doc](https://rust-lang.github.io/wg-async/vision/) took place under the auspices of the working group, for example. However, the group lacks decision making power and doesn't have a strong incentive to truly "coallesce" behind a shared vision, so it remains more a "set of individual voices" that can still leave the general purpose teams without clear guidance. +* It advises the more general teams (typically [Lang][] and [Libs-API][]) on async-related matters. The authoring of the (mildly dated) [async vision doc](https://rust-lang.github.io/wg-async/vision/) took place under the auspices of the working group, for example. However, the group lacks decision making power and doesn't have a strong incentive to coallesce behind a shared vision, so it remains more a "set of individual voices" that does not provide the general purpose teams with clear guidance. We plan to propose one or more permanent teams to meet these same set of needs. The expectation is that these will be subteams under the [Lang] and [Libs] top-level teams. From 37b8634e3154598bef9bde82d54644f334849e94 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 24 Jun 2024 06:37:35 -0400 Subject: [PATCH 18/19] add link to Tower --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index ed2460572c1..6fc239e1b92 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -12,7 +12,7 @@ This is a proposed flagship goal for 2024h2 covering **async Rust**. You can [re The overall goal is **bringing the Async Rust experience closer to parity with sync Rust**. We have identified three high-priority goals that we believe would do the most to improve async over the long term: -* [resolving the "send bound problem"](#resolve-the-send-bound-problem), thus enabling foundational, generic traits like Tower's [`Service`]() trait; +* [resolving the "send bound problem"](#resolve-the-send-bound-problem), thus enabling foundational, generic traits like Tower's [`Service`](https://docs.rs/tower/latest/tower/trait.Service.html) trait; * [stabilizing async closures](#stabilize-async-closures), thus enabling richer, combinator APIs like sync Rust's [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html); * [reorganizing the async WG](#reorganize-the-async-wg), so the project can benefit from a group of async rust experts with deep knowledge of the space that can align around a shared vision; From 0b98b6dbaa63f128be70db3580d755d2cd9a2b04 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 25 Jun 2024 13:25:27 -0400 Subject: [PATCH 19/19] Update text/0000-async-project-goal-2024h2.md Co-authored-by: Travis Cross --- text/0000-async-project-goal-2024h2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-async-project-goal-2024h2.md b/text/0000-async-project-goal-2024h2.md index 6fc239e1b92..2d268de1f3e 100644 --- a/text/0000-async-project-goal-2024h2.md +++ b/text/0000-async-project-goal-2024h2.md @@ -178,7 +178,7 @@ Our eventual goal is to provide Rust users building on async with Here is a detailed list of the work to be done and who is expected to do it. This table includes the work to be done by owners and the work to be done by Rust teams (subject to approval by the team in an RFC/FCP). The overall owners of the async effort (and authors of this goal document) are [tmandry][] and [nikomatsakis][]. We have identified owners for subitems below; these may change over time. * The ![Funded][] badge indicates that the owner has committed and work will be funded by their employer or other sources. -* The ![Not founded][] badge indictes that there is a willing owner but they need funding to pursue the goal. Depending on the owner's individual circumstances, this could be support/authorizaiton from their employer, grants, or contracting. +* The ![Not funded][] badge indicates that there is a willing owner but they need funding to pursue the goal. Depending on the owner's individual circumstances, this could be support/authorization from their employer, grants, or contracting. * The ![Team][] badge indicates a requirement where Team support is needed. | Subgoal | Owner(s) or team(s) | Status |