Model eval as one call returning stream + future - #24
Merged
Conversation
`interface eval` drops its `evaluation` resource for a single synchronous
import: `eval(js, send: stream<string>) -> tuple<stream<string>,
future<result<string, error>>>`. The channels are component-model streams
and the completion a future, so every lifetime question now has the
CABI's answer: "no more values" is the stream closing, "already
completed" cannot be asked twice of a future, and a fire-and-forget eval
is a dropped reader the host's eventual write sees as `dropped`. The
`finished` error case goes away with them.
This also removes the macrotask deferral the host carried against
polyengine#280. Measured on the same build and click path: a subtask
import settling in the microtask checkpoint after `handle-event`'s
initial activation returns is lost, while a future-typed import settling
at the same moment (even from an already-resolved promise) is delivered.
Future and stream writes take a different path through the runtime than
subtask settlement, so the shape sidesteps the bug rather than papering
over it.
Guest: `Evaluator::send` is synchronous and at most one write may be in
flight per stream end, so sends stage into a `Vec` drained by a spawned
task that owns the writer for the drain (the renderer's own
`stream`/`pending` pattern). The `recv` reader is moved out of its slot
for each await and put back. Owner-lifetime handling is unchanged.
Host: returns `[AsyncIterable, Promise]` synchronously; the runtime lowers
both ("Lowering accepts the natural JS producers"). The stream is closed
before the future resolves so a reader never observes completion with a
value still in flight. Fixture and end-to-end tests are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #23.
interface evalbecomes a single sync import:eval: func(js: string, send: stream<string>) -> tuple<stream<string>, future<result<string, error>>>; variant error { invalid-js(string), communication(string) }Why: the CABI now owns every lifetime question (stream close = no more values; a future is read once; fire-and-forget = dropped reader), so the
finishederror case and the resource are gone. And it removes the macrotask workaround for polyengine#280: measured on the same build, a subtask import settling right afterhandle-event's initial activation is lost, while a future-typed import settling at the same moment is delivered (comment on #280 has the matrix).Guest (
src/document.rs): sends stage into aVecdrained by a spawned writer-owning task (one in-flight write per end); the recv reader is moved out of its slot per await. Owner-lifetime scheme unchanged.Host (
host/src/eval.ts): returns[AsyncIterable, Promise]synchronously, lowered by the runtime; stream closes before the future resolves. No deferral anywhere.Fixture and
eval_component_test.tsunchanged and green; unit tests rewritten for the new API. Fulljust check/fixtures/example counter/testpass.Automerge armed (merge commit).