11# Concurrency Explainer
22
3- This document contains a high-level summary of the native concurrency support
4- added as part of [ WASI Preview 3 ] , providing background for understanding the
5- definitions in the [ WIT ] , [ AST explainer] , [ binary format] and [ Canonical ABI
6- explainer ] documents that are gated by the 🔀 (async) and 🧵 (threading) emojis.
3+ This document contains a high-level summary of the native concurrency support,
4+ providing background for understanding the definitions in the [ WIT ] , [ AST
5+ explainer] , [ binary format] and [ Canonical ABI explainer ] documents that are
6+ gated by the 🔀 (async) and 🧵 (threading) emojis.
77
88* [ Goals] ( #goals )
99* [ Summary] ( #summary )
@@ -34,9 +34,9 @@ explainer] documents that are gated by the 🔀 (async) and 🧵 (threading) emo
3434
3535## Goals
3636
37- Refining the Component Model's high-level [ goals ] ( ../high-level/Goals.md ) and
38- [ use cases] ( ../high-level/UseCases.md ) , [ WASI Preview 3 ] adds the following
39- concurrency-specific goals and use cases:
37+ With the release of [ WASI ] 0.3, the following concurrency-specific goals and
38+ use cases are added, refining the Component Model's high-level
39+ [ goals ] ( ../high-level/Goals.md ) and [ use cases] ( ../high-level/UseCases.md ) :
4040
4141* Integrate with idiomatic source-language concurrency features including:
4242 * ` async ` functions in languages like C#, JS, Python, Rust and Swift
@@ -92,7 +92,7 @@ invariant is necessary to allow non-`async` component exports to be called in
9292synchronous contexts (like event listeners, callbacks, getters, setters and
9393constructors).
9494
95- The new async ABI can be used alongside or instead of the existing Preview 2
95+ The new async ABI can be used alongside or instead of the existing [ WASI ] 0. 2
9696"sync ABI" to call or implement any ` async ` -typed functions. When * calling* an
9797imported function via the async ABI, if the ` async ` callee [ blocks] ( #blocking ) ,
9898control flow is returned immediately to the caller, and the callee continues
@@ -108,7 +108,7 @@ can compile directly to components exporting `async` functions without having
108108to be rewritten to use source-language concurrency mechanisms (like callbacks,
109109` async ` /` wait ` , coroutines, etc). For example, traditional C programs with a
110110` main() ` and calls to ` read() ` , ` write() ` and ` select() ` can run without change
111- in the Preview 3 ` wasi:cli/command ` world, which exports `run: async func() ->
111+ in the [ WASI ] 0. 3 ` wasi:cli/command ` world, which exports `run: async func() ->
112112result` . Thus, ` async` in WIT does not require the same kind of transitive
113113source-code changes as source-level ` async ` in languages like C#, Python, JS,
114114Rust and Dart.
@@ -911,9 +911,10 @@ the Component Model has [Component Invariant] #2. This is enforced by the
911911[ Canonical ABI] ( CanonicalABI.md#embedding ) using strategically placed traps and
912912boolean flags on component instances.
913913
914- With Preview 3, a desirable outcome is that if our component imports ` imp ` and
915- exports ` exp ` as ` async ` functions, then the following JS code could run the
916- two ` exp ` calls concurrently just like if they were JS ` async ` functions:
914+ With native concurrency support, what we'd naturally expect is that if our
915+ component imports ` imp ` and exports ` exp ` as ` async ` functions, then the
916+ following JS code could run the two ` exp ` calls concurrently, as if they were JS
917+ ` async ` functions:
917918``` js
918919import source component from ' ./component.wasm' ;
919920async function imp () {
@@ -1003,7 +1004,7 @@ task" to which work can be dispatched (e.g., via the `setInterval()` or
10031004concurrency] , these background tasks are new task tree roots (siblings to the
10041005roots created when component exports are called by the host).
10051006
1006- As a Preview 3 follow-up [ TODO] ( #TODO ) , component type definitions should be
1007+ As a post-0.3.0 follow-up [ TODO] ( #TODO ) , component type definitions should be
10071008extended to allow an ` async ` effect that declares that component instantiation
10081009is allowed to [ block] ( #blocking ) . This would be necessary to implement, e.g.,
10091010JS [ top-level ` await ` ] or I/O in C++ constructors executing during ` start ` .
@@ -1013,7 +1014,7 @@ JS [top-level `await`] or I/O in C++ constructors executing during `start`.
10131014
10141015At an ABI level, native async in the Component Model defines for every
10151016` async ` -typed function a non-blocking core function signature that can be
1016- used instead of or in addition to the existing (Preview-2-defined ) synchronous
1017+ used instead of or in addition to the existing ([ WASI ] 0.2 ) synchronous
10171018core function signature. This non-blocking core function signature is intended
10181019to be called or implemented by generated bindings which then map the low-level
10191020core async protocol to the languages' higher-level native concurrency features.
@@ -1406,7 +1407,7 @@ instance lifetimes are flexible in this manner and don't have an obvious end
14061407conventionally ends right after ` main() ` returns), the host still needs to
14071408understand the expectations of component authors to enable portability.
14081409
1409- Before the addition of native concurrency support in Preview 3, a natural
1410+ Before the addition of native concurrency support in [ WASI ] 0. 3, a natural
14101411expectation is that, in the absence of atypical scenarios like timeouts or quota
14111412exhaustion, a component author can expect that their component instance will not
14121413be abruptly terminated during the execution of contained Core WebAssembly code.
@@ -1462,16 +1463,16 @@ waiting on `async` operations to complete.
14621463
14631464To resolve this tension, threads are implicitly distinguished by a "keep-alive"
14641465flag that determines whether the expectation is that the existence of the thread
1465- is intended to keep the containing component instance alive. In the initial
1466- release of Preview 3, this "keep-alive" flag is default * set* for the [ implicit
1467- thread ] ( #summary ) created for a task and default * cleared* for the explicit
1468- threads created by ` thread.new-indirect ` . In particular, this means that an
1466+ is intended to keep the containing component instance alive. In [ WASI ] 0.3,
1467+ this "keep-alive" flag is default * set* for the [ implicit thread ] ( #summary )
1468+ created for a task and default * cleared* for the explicit threads created by
1469+ ` thread.new-indirect ` . In particular, this means that an
14691470` async callback ` -lifted function will keep its containing component instance
14701471alive until it returns the ` EXIT ` code (` 0 ` ).
14711472
14721473As an example, in JavaScript, the Service Worker API's [ ` waitUntil ` ] method
1473- would delay returning the ` EXIT ` code. In the initial 0.3.0 release without
1474- cooperative threads (🧵), [ ` setInterval ` ] would also unfortunately delay
1474+ would delay returning the ` EXIT ` code. In 0.3.0, without cooperative threads
1475+ (🧵), [ ` setInterval ` ] would also unfortunately delay
14751476returning the ` EXIT ` code and thus, without guest code intervention, would keep
14761477component instances alive until timeout limits were hit. The release of
14771478cooperative threads would offer a solution to this problem, but an awkward one.
@@ -1494,10 +1495,9 @@ the whole tree would be kept alive.
14941495
14951496## TODO
14961497
1497- Native async support is being proposed incrementally. The following features
1498- will be added in future chunks roughly in the order listed to complete the full
1499- "async" story, with a TBD cutoff between what's in [ WASI Preview 3] and what
1500- comes after:
1498+ Native async support is being added incrementally. Beyond what's currently
1499+ specified, the following features are being considered for addition to complete
1500+ the concurrency story:
15011501* remove the temporary trap mentioned above that occurs when a ` read ` and
15021502 ` write ` of a stream/future happen from within the same component instance
15031503* zero-copy forwarding/splicing
@@ -1613,7 +1613,7 @@ comes after:
16131613[ wasm-gc ] : https://github.com/WebAssembly/gc/blob/main/proposals/gc/MVP.md
16141614[ wasi-libc ] : https://github.com/WebAssembly/wasi-libc
16151615
1616- [ WASI Preview 3 ] : https://github.com/WebAssembly/WASI/tree/main/wasip2#looking-forward-to-preview-3
1616+ [ WASI ] : https://github.com/WebAssembly/WASI
16171617[ Runtime Instantiation ] : https://github.com/WebAssembly/component-model/issues/423
16181618
16191619[ Top-level `await` ] : https://github.com/tc39/proposal-top-level-await
0 commit comments