Skip to content

Commit d95c116

Browse files
committed
Also prohibit blocking during the start function
1 parent 34ed26f commit d95c116

File tree

1 file changed

+20
-36
lines changed

1 file changed

+20
-36
lines changed

design/mvp/Concurrency.md

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -840,42 +840,22 @@ Despite the above, the following scenarios do behave deterministically:
840840

841841
## Interaction with the start function
842842

843-
Since any component-level function with an empty signature can be used as a
844-
[`start`] function, there's nothing to stop an `async`-lifted function from
845-
being used as a `start` function. Async start functions are useful when
846-
executing general-purpose code at initialization time, e.g.:
847-
* If the top-level scripts of a scripting language are executed by the `start`
848-
function, asychrony arises from regular use of the language's concurrency
849-
features. For example, in JS, this takes the form of [top-level `await`].
850-
* If C++ or other OOPLs global object constructors are executed by the `start`
851-
function, these can execute general-purpose code which may use concurrent
852-
I/O APIs.
853-
854-
Since component `start` functions are already defined to be executed
855-
synchronously before the component is considered initialized and ready for its
856-
exports to be called, the natural thing for `start` to do when calling an
857-
`async`-lifted function is wait for the callee to reach the ["returned"
858-
state](#returning). This gives `async` `start` functions a simple way to do
859-
concurrent initialization and signal completion using the same language
860-
bindings as regular `async` `export` functions.
861-
862-
However, as explained above, an async task can always continue executing after
863-
reaching the "returned" state and thus an async task spawned by `start` may
864-
continue executing even after the component instance is initialized and
865-
receiving export calls. These post-return `start`-tasks can be used by the
866-
language toolchain to implement traditional "background tasks" (e.g., the
867-
`setInterval()` or `requestIdleCallback()` JavaScript APIs). From the
868-
perspective of [structured concurrency], these background tasks are new task
869-
tree roots (siblings to the roots created when component exports are
870-
called by the host). Thus, subtasks and threads spawned by the background task
871-
will have proper async callstacks as used to define reentrancy and support
872-
debugging/profiling/tracing.
873-
874-
In future, when [runtime instantiation] is added to the Component Model, the
875-
component-level function used to create a component instance could be lowered
876-
with `async` to allow a parent component to instantiate child components
877-
concurrently, relaxing the fully synchronous model of instantiation supported
878-
by declarative instantiation and `start` above.
843+
All start functions (both component-level and Core WebAssembly start functions
844+
called via `core instance` definition) implicitly have the component-level
845+
function type `func()`, i.e., they are synchronous and take and return no
846+
arguments. Based on the above description of synchronous functions, this means
847+
that start functions may not block before returning. However, if a
848+
component-level start function is lifted using the async ABI, it *may* block
849+
after calling `task.return`, and may thus serve as a long-running "background
850+
task" to which work can be dispatched (e.g., via the `setInterval()` or
851+
`requestIdleCallback()` JavaScript APIs). From the perspective of [structured
852+
concurrency], these background tasks are new task tree roots (siblings to the
853+
roots created when component exports are called by the host).
854+
855+
As a Preview 3 follow-up [TODO](#TODO), component type definitions should be
856+
extended to allow an `async` effect that declares that component instantiation
857+
is allowed to [block](#blocking). This would be necessary to implement, e.g.,
858+
JS [top-level `await`] or I/O in C++ constructors executing during `start`.
879859

880860

881861
## Async ABI
@@ -1279,6 +1259,10 @@ comes after:
12791259
`write` of a stream/future happen from within the same component instance
12801260
* zero-copy forwarding/splicing
12811261
* some way to say "no more elements are coming for a while"
1262+
* add an `async` effect on `component` type definitions allowing a component
1263+
type to block during instantiation
1264+
* add an `async` effect on `resource` type definitions allowing a resource
1265+
type to block during its destructor
12821266
* `recursive` function type attribute: allow a function to opt in to
12831267
recursive [reentrance], extending the ABI to link the inner and
12841268
outer activations

0 commit comments

Comments
 (0)