@@ -19,7 +19,6 @@ summary of the motivation and animated sketch of the design in action.
19
19
* [ Structured concurrency] ( #structured-concurrency )
20
20
* [ Waiting] ( #waiting )
21
21
* [ Backpressure] ( #backpressure )
22
- * [ Starting] ( #starting )
23
22
* [ Returning] ( #returning )
24
23
* [ Examples] ( #examples )
25
24
* [ Interaction with multi-threading] ( #interaction-with-multi-threading )
@@ -218,44 +217,30 @@ private resources (like linear memory), requiring the component to be able to
218
217
exert * backpressure* to allow some tasks to finish (and release private
219
218
resources) before admitting new async export calls. To do this, a component may
220
219
call the ` task.backpressure ` built-in to set a "backpressure" flag that causes
221
- subsequent export calls to immediately return in the [ starting] ( #starting )
222
- state without calling the component's Core WebAssembly code.
220
+ subsequent export calls to immediately return in the " starting" state without
221
+ calling the component's Core WebAssembly code.
223
222
224
- Once backpressure is enabled, the current task can [ wait] ( #waiting ) for
225
- existing tasks to finish and release their associated resources. Thus, a task
226
- can [ wait] ( #waiting ) with or without backpressure, depending on whether it
223
+ Once task enables backpressure, it can [ wait] ( #waiting ) for existing tasks to
224
+ finish and release their associated resources. Thus, a task can choose to
225
+ [ wait] ( #waiting ) with or without backpressure enabled , depending on whether it
227
226
wants to accept new accept new export calls while waiting or not.
228
227
229
228
See the [ ` canon_task_backpressure ` ] function and [ ` Task.enter ` ] method in the
230
229
Canonical ABI explainer for the setting and implementation of backpressure.
231
230
232
- ### Starting
233
-
234
- When a component asynchronously lifts a function, instead of the function
235
- eagerly receiving its lowered parameters (as a synchronous function would) the
236
- asynchronously-lifted Core WebAssembly function is passed an empty list of
237
- arguments and must instead call an imported [ ` task.start ` ] built-in to lower
238
- and receive its arguments.
239
-
240
- The main reason to have ` task.start ` is so that an overloaded component can
241
- enable [ backpressure] ( #backpressure ) and then [ wait] ( #waiting ) for existing
242
- tasks to finish before the receiving the arguments to the current task. See the
243
- [ ` canon_task_start ` ] function in the Canonical ABI explainer for more details.
244
-
245
- Before a task has called ` task.start ` , it is considered in the "starting"
246
- state. After calling ` task.start ` , the task is in a "started" state.
231
+ Once a task is allowed to start according to these backpressure rules, its
232
+ arguments are lowered into the callee's linear memory and the task is in
233
+ the "started" state.
247
234
248
235
### Returning
249
236
250
- Symmetric to starting, the way a Core WebAssembly function returns its value is
251
- by calling [ ` task.return ` ] , passing the core values that are to be lifted.
237
+ The way an async Core WebAssembly function returns its value is by calling
238
+ [ ` task.return ` ] , passing the core values that are to be lifted.
252
239
253
240
The main reason to have ` task.return ` is so that a task can continue execution
254
241
after returning its value. This is useful for various finalization tasks (such
255
242
as logging, billing or metrics) that don't need to be on the critical path of
256
- returning a value to the caller. (It also subsumes and generalizes the
257
- Canonical ABI's ` post_return ` function used by synchronous functions to release
258
- memory.)
243
+ returning a value to the caller.
259
244
260
245
A task may not call ` task.return ` unless it is in the "started" state. Once
261
246
` task.return ` is called, the task is in the "returned" state. A task can only
@@ -273,12 +258,9 @@ replaced with `...` to focus on the overall flow of function calls.
273
258
(import "fetch" (func $fetch (param "url" string) (result (list u8))))
274
259
(core module $Main
275
260
(import "" "fetch" (func $fetch (param i32 i32) (result i32)))
276
- (import "" "task.start" (func $task_start (param i32)))
277
261
(import "" "task.return" (func $task_return (param i32)))
278
262
(import "" "task.wait" (func $wait (param i32) (result i32)))
279
- (func (export "summarize")
280
- ...
281
- call $task_start ;; receive the list of strings arguments
263
+ (func (export "summarize") (param i32 i32)
282
264
...
283
265
loop
284
266
...
@@ -296,12 +278,10 @@ replaced with `...` to focus on the overall flow of function calls.
296
278
)
297
279
)
298
280
(canon lower $fetch async (core func $fetch'))
299
- (canon task.start (core func $task_start))
300
281
(canon task.return (core func $task_return))
301
282
(canon task.wait (core func $task_wait))
302
283
(core instance $main (instantiate $Main (with "" (instance
303
284
(export "fetch" (func $fetch'))
304
- (export "task.start" (func $task_start))
305
285
(export "task.return" (func $task_return))
306
286
(export "task.wait" (func $task_wait))
307
287
))))
@@ -321,13 +301,13 @@ reclaim the memory passed arguments or use the results that have now been
321
301
written to the outparam memory.
322
302
323
303
Because the ` summarize ` function is ` canon lift ` ed with ` async ` , its core
324
- function type has no params or results, since parameters are passed in via
325
- ` task.start ` and results are passed out via ` task.return ` . It also means that
326
- multiple ` summarize ` calls can be active at once: once the first call to
327
- ` task.wait ` blocks, the runtime will suspend its callstack (fiber) and start a
328
- new stack for the new call to ` summarize ` . Thus, ` summarize ` must be careful to
329
- allocate a separate linear-memory stack in its entry point, if one is needed,
330
- and to save and restore this before and after calling ` task.wait ` .
304
+ function type has no results, since results are passed out via ` task.return ` .
305
+ It also means that multiple ` summarize ` calls can be active at once: once the
306
+ first call to ` task.wait ` blocks, the runtime will suspend its callstack
307
+ (fiber) and start a new stack for the new call to ` summarize ` . Thus,
308
+ ` summarize ` must be careful to allocate a separate linear-memory stack in its
309
+ entry point, if one is needed, and to save and restore this before and after
310
+ calling ` task.wait ` .
331
311
332
312
(Note that, for brevity this example ignores the ` memory ` and ` realloc `
333
313
immediates required by ` canon lift ` and ` canon lower ` to allocate the ` list `
@@ -345,12 +325,9 @@ not externally-visible behavior.
345
325
(import "fetch" (func $fetch (param "url" string) (result (list u8))))
346
326
(core module $Main
347
327
(import "" "fetch" (func $fetch (param i32 i32) (result i32)))
348
- (import "" "task.start" (func $task_start (param i32)))
349
328
(import "" "task.return" (func $task_return (param i32)))
350
329
(import "" "task.wait" (func $wait (param i32) (result i32)))
351
- (func (export "summarize") (result i32)
352
- ...
353
- call $task_start ;; receive the list of strings arguments
330
+ (func (export "summarize") (param i32 i32) (result i32)
354
331
...
355
332
loop
356
333
...
@@ -372,12 +349,10 @@ not externally-visible behavior.
372
349
)
373
350
)
374
351
(canon lower $fetch async (core func $fetch'))
375
- (canon task.start (core func $task_start))
376
352
(canon task.return (core func $task_return))
377
353
(canon task.wait (core func $task_wait))
378
354
(core instance $main (instantiate $Main (with "" (instance
379
355
(export "fetch" (func $fetch'))
380
- (export "task.start" (func $task_start))
381
356
(export "task.return" (func $task_return))
382
357
(export "task.wait" (func $task_wait))
383
358
))))
@@ -388,9 +363,8 @@ not externally-visible behavior.
388
363
```
389
364
While this example spawns all the subtasks in the initial call to ` summarize ` ,
390
365
subtasks can also be spawned from ` cb ` (even after the call to ` task.return ` ).
391
- It's also possible for ` summarize ` to wait to call ` task.start ` from ` cb ` or,
392
- conversely, for ` task.return ` to be called eagerly in the initial call to
393
- ` summarize ` .
366
+ It's also possible for ` summarize ` to call ` task.return ` called eagerly in the
367
+ initial core ` summarize ` call.
394
368
395
369
The ` $event ` and ` $payload ` parameters passed to ` cb ` are the same as the return
396
370
values from ` task.wait ` in the previous example. The precise meaning of these
@@ -476,7 +450,6 @@ features will be added in future chunks to complete "async" in Preview 3:
476
450
[ Lift and Lower Definitions ] : Explainer.md#canonical-definitions
477
451
[ Lifted ] : Explainer.md#canonical-definitions
478
452
[ Canonical Built-in ] : Explainer.md#canonical-built-ins
479
- [ `task.start` ] : Explainer.md#-async-built-ins
480
453
[ `task.return` ] : Explainer.md#-async-built-ins
481
454
[ `task.wait` ] : Explainer.md#-async-built-ins
482
455
[ `thread.spawn` ] : Explainer.md#-threading-built-ins
@@ -488,7 +461,6 @@ features will be added in future chunks to complete "async" in Preview 3:
488
461
[ `canon_lower` ] : CanonicalABI.md#canon-task-wait
489
462
[ `canon_task_wait` ] : CanonicalABI.md#-canon-taskwait
490
463
[ `canon_task_backpressure` ] : CanonicalABI.md#-canon-taskbackpressure
491
- [ `canon_task_start` ] : CanonicalABI.md#-canon-taskstart
492
464
[ `canon_task_return` ] : CanonicalABI.md#-canon-taskreturn
493
465
[ `Task` ] : CanonicalABI.md#runtime-state
494
466
[ `Task.enter` ] : CanonicalABI.md#runtime-state
0 commit comments