Runs the wizard child as its own persisted run - #47
Merged
Conversation
A durable run reaching a `core.subchart` used to be refused: the
`{:start_child, _, _}` instruction was `Statifier.Session`'s and nobody
else's, so `signup_onboarding` routed down `on_error`. The durable
driver executes it now, and this app is the host that wires it.
`StatifierExamples.Persistence` gains `list_runs_by_metadata/2`, which
is what opts an adapter into durable subcharts at all - the driver
refuses to start a child over a store that cannot enumerate one. The
Ecto adapter's version is a `jsonb @>` query and SQLite has no such
operator, so this is the containment test in Elixir, with the table
scan it costs stated rather than hidden.
`Durable` routes the subchart type to
`StatifierBlocks.Runtime.DurableSubchart`, carries a `chart_resolver:`
so a finished child can answer its parent, cascades `abandon/1` into
live children, and resumes a run by id alone.
Three defects the browser captures found, none of which had a test
asking for them: the child's timers and asynchronous jobs were scoped
to the parent's run id, the child could not be opened by URL because
the page compiled the wrong recipe, and a cancelled run raised in
`finish/2`, which knew only three of the four stored statuses.
Both family deps move to interim git pins, re-pin to Hex owed:
statifier_persistence at 1416a7b for sp-2yx's widened dispatch
context, statifier_blocks at 05f0a4a for the durable handler.
`mix_deps_test.exs` asserts both, so the re-pin cannot be forgotten
quietly.
se-6ag
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.
Closes se-6ag.
The durable-subchart proof: the wizard child runs as its own persisted
run, exercised through a cold restart and through cancel, with captures.
signup_onboardingused to reach itscore.subchartand be refused -{:start_child, _, _}wasStatifier.Session's instruction and nobodyelse's, so the durable driver routed the run down
on_error. It is not anymore.
StatifierPersistence.Driverexecutes the same instruction bycreating the child as an ordinary run with linkage metadata, and this app is
the host that wires it.
What a reader sees
Press Run on
/editor?doc=signup_onboardingand the feed says:That id opens as a run of its own at
/editor?doc=signup_wizard&run=<parent>/blk_so_wizard/0, on the positionthe child actually reached. Drive it to the end there and the parent
finishes too, without anyone pressing anything on the parent's page. Press
Stop on the parent instead and the child is cancelled with it, keeping
its stored position byte-identical.
The host-side pieces
StatifierExamples.Persistence.list_runs_by_metadata/2is new, andexporting it is what opts this adapter into durable subcharts at all: the
driver refuses to start a child over a store that cannot enumerate one.
The Ecto adapter's version is a
jsonb @>query and SQLite has no suchoperator, so this is the containment test written out in Elixir, with the
table scan it costs stated in the moduledoc rather than hidden. The
package's conformance suite now generates its child-listing case here and
passes it.
Durable's dispatch fun routesstatifier_blocks:subcharttoStatifierBlocks.Runtime.DurableSubchartbeforeCharts.dispatch/3isreached.
Charts.dispatch/3still refuses the type by name, now spelled{:subchart_not_a_sync_call, type}- the old:durable_subchart_unsupportedis no longer true of this app.
chart_resolver:on the driver is how the child's driver reaches theparent's chart, which it does not hold. The package cannot supply it, so
this app walks the documents it publishes and matches on content hash.
Durable.abandon/1cascades into the run's children, guarded on thestore's own
child_listing_supported?/1.Durable.resume/1picks the compile recipe off the stored record.Three defects the browser captures found, all fixed here
The proof was captured before it was believed, and the captures earned their
place. None of these had a test asking for them.
the parent's driver with only the machine swapped, so the same
effects:executor ran the child's effects - and it keyed on the run id it closed
over. The wizard's 24-hour wait and its abandonment reminder were stored
as jobs against the parent, where they would fire into a chart with no
such event while the child waited forever. Both consumers now key on
context.run_id.document with the root recipe and a child's stored identity is keyed on
the child recipe, so the page's resume was refused on identity - two
compiles of one document, and the guard doing its job for a reader who
could not act on it.
Durable.resume/1reads the recipe off the record.:cancelledis a fourth storedstatus as of
statifier_persistence0.4.0, andfinish/2had clausesfor the three that existed before, so opening a cancelled child raised a
FunctionClauseError. Cancellation retains, so a cancelled run isprecisely a run somebody opens.
Interim pins, re-pin to Hex owed
Both are recorded for the ledger and both retire on the operator's publish.
statifier_persistence1416a7b98ce70efe0511050d23dd9cc8f12d0d3eDriver.dispatch_context/0to carry:invoke; without the whole effect a dispatch fun cannot reachsrcand the handler raises. Everything else ADR-0008 needs is in 0.4.0.statifier_blocks05f0a4ab0c9a1adb1c8857d0b5642a8b19cc7e98StatifierBlocks.Runtime.DurableSubchartlanded after 0.13.0.test/statifier_examples/mix_deps_test.exsasserts both pins inmix.exsand
mix.lock, so the re-pin has to be a deliberate edit rather thansomething that can be forgotten quietly.
Verification
Full
mix qualitygreen: 254 tests, 78.0% coverage, dialyzer and credoclean. Every new test asserting
lib/behaviour was sabotaged and confirmedred first, with the mutation noted above it.
/wurk:verify --unattendedhas an empty backlog here - no plan stage ran,the bead was fully specified - so the substitute pass applies, and each
acceptance criterion was machine-checked against the live artefact:
<parent>/blk_so_wizard/0and the exact linkage map; capture 3 shows it open in the editor:failed/host:stopped, child:cancelled, position byte-identical; capture 4:completed026-screens/,se-6ag-prefixedCaptures were taken against a private instance on port 8649, driven over
CDP (the Chrome extension was not connected this session). The frozen stack
on 8645 / 8643 / 8642 / 4002 was not touched, restarted or repointed.
Deferred to the operator
docs/demo-script.mdsection 11 still describes the refusal as the shippedbehaviour, and names this change as its own deliberate follow-up. Campaign
ruling R25-4 is capture-only - the demo script is not edited - so it is left
stale and flagged rather than corrected here. It wants a bead.