Skip to content

Commit 0c5fa47

Browse files
committed
Update stale stream/future summary in Async.md
1 parent 1fb806f commit 0c5fa47

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

design/mvp/Async.md

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -132,33 +132,41 @@ Thus, backpressure combined with the partitioning of low-level state provided
132132
by the Component Model enables sync and async code to interoperate while
133133
preserving the expectations of both.
134134

135-
In addition to being able to define and call whole functions asynchronously,
136-
the `stream` and `future` types can be used in function signatures to pass
137-
parameters and results incrementally over time, achieving finer-grained
138-
concurrency. Streams and futures are thus not defined to be free-standing
139-
resources with their own internal memory buffers (like a traditional channel or
140-
pipe) but, rather, more-primitive control-flow mechanisms that synchronize the
141-
incremental passing of parameters and results during cross-component calls.
142-
Higher-level resources like channels and pipes could then be defined in terms
143-
of these lower-level `stream` and `future` primitives, e.g.:
144-
135+
Lastly, WIT is extended with two new type constructors—`future<T>` and
136+
`stream<T>`—to allow new WIT interfaces to explicitly represent concurrency in
137+
*both* the sync and async ABIs in way that can be bound to many language's
138+
idiomatic futures, promises, streams and channels. Futures and streams are,
139+
semantically, unidirectional unbuffered channels with a dynamically-enforced
140+
[session type] describing the passing of exactly 1 or 0..N values, resp., with
141+
the additional ability for the reader end to signal a loss of interest
142+
to the writer end. Thus, futures and streams are more primitive concepts than,
143+
e.g., Unix pipes (which have an associated intermediate memory buffer that
144+
values are copied into and out of). Rather, streams could be used to *define*
145+
higher-level concepts like pipes, HTTP response bodies or stream transformers.
146+
E.g.:
145147
```wit
146148
resource pipe {
147-
constructor(buffer-size: u32);
148-
write: func(bytes: stream<u8>) -> result;
149-
read: func() -> stream<u8>;
149+
constructor(buffer-size: u32);
150+
write: func(bytes: stream<u8>) -> result;
151+
read: func() -> stream<u8>;
152+
}
153+
resource response {
154+
constructor(body: stream<u8>);
155+
consume-body: func() -> stream<u8>;
150156
}
157+
transform: func(in: stream<point>) -> stream<point>;
151158
```
152-
153-
but also many other domain-specific concurrent resources like WASI HTTP request
154-
and response bodies or WASI blobs. Streams and futures are however high-level
155-
enough to be bound automatically to many source languages' built-in concurrency
156-
features like futures, promises, streams, generators and iterators, unlike
157-
lower-level concurrency primitives (like callbacks or `wasi:io@0.2.0`
158-
`pollable`s). Thus, the Component Model seeks to provide the lowest-level
159-
fine-grained concurrency primitives that are high-level and idiomatic enough to
160-
enable automatic generation of usable language-integrated bindings.
161-
159+
A `future` or `stream` in a function signature always refers to the transfer of
160+
unique ownership of the *readable end* of the future or stream. To get a
161+
*writable end*, a component must first internally create a (readable, writable)
162+
end pair (via the [`{stream,future}.new`] built-ins) and then pass the readable
163+
end elsewhere (e.g., in the above WIT, as a parameter to an imported
164+
`pipe.write` or as a result of an exported `transform`). Given the readable or
165+
writable end of a future or stream (represented as an `i32` index into the
166+
component instance's handle table), Core WebAssembly can then call a
167+
[`{stream,future}.{read,write}`] built-in to synchronously or asynchronously
168+
copy into or out of a caller-provided buffer of Core WebAssembly linear (or,
169+
soon, GC) memory.
162170

163171
## Concepts
164172

@@ -1124,6 +1132,7 @@ comes after:
11241132
[CPS Transform]: https://en.wikipedia.org/wiki/Continuation-passing_style
11251133
[Event Loop]: https://en.wikipedia.org/wiki/Event_loop
11261134
[Structured Concurrency]: https://en.wikipedia.org/wiki/Structured_concurrency
1135+
[Session Types]: https://en.wikipedia.org/wiki/Session_type
11271136
[Unit]: https://en.wikipedia.org/wiki/Unit_type
11281137
[Thread-local Storage]: https://en.wikipedia.org/wiki/Thread-local_storage
11291138
[FS or GS Segment Base Address]: https://docs.kernel.org/arch/x86/x86_64/fsgs.html
@@ -1144,6 +1153,8 @@ comes after:
11441153
[`waitable-set.wait`]: Explainer.md#-waitable-setwait
11451154
[`waitable-set.poll`]: Explainer.md#-waitable-setpoll
11461155
[`thread.spawn*`]: Explainer.md#-threadspawn_ref
1156+
[`{stream,future}.new`]: Explainer.md#-streamnew-and-futurenew
1157+
[`{stream,future}.{read,write}`]: Explainer.md#-streamread-and-streamwrite
11471158
[ESM-integration]: Explainer.md#ESM-integration
11481159

11491160
[Canonical ABI Explainer]: CanonicalABI.md

0 commit comments

Comments
 (0)