Skip to content

Commit 4bf915b

Browse files
committed
Also prohibit blocking during the start function
1 parent 0eb5630 commit 4bf915b

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
@@ -841,42 +841,22 @@ Despite the above, the following scenarios do behave deterministically:
841841

842842
## Interaction with the start function
843843

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

881861

882862
## Async ABI
@@ -1282,6 +1262,10 @@ comes after:
12821262
`write` of a stream/future happen from within the same component instance
12831263
* zero-copy forwarding/splicing
12841264
* some way to say "no more elements are coming for a while"
1265+
* add an `async` effect on `component` type definitions allowing a component
1266+
type to block during instantiation
1267+
* add an `async` effect on `resource` type definitions allowing a resource
1268+
type to block during its destructor
12851269
* `recursive` function type attribute: allow a function to opt in to
12861270
recursive [reentrance], extending the ABI to link the inner and
12871271
outer activations

0 commit comments

Comments
 (0)