Repository navigation
Persist outputs to a store - #52
Open
SimonHeybrock wants to merge 4 commits into
Open
SimonHeybrock wants to merge 4 commits into
SimonHeybrock wants to merge 4 commits into
Conversation
…ount A record of an accumulator's state, a freeze's included, is logged as the accumulator and its number of pushes; the views list its rows when it is read, from the template's typed values that opening now logs. This marks records of states, which the restart rule needs. The backend takes a store. submit(persist=), freeze(persist=), and client.persist log persist requests; a worker writes the outputs named when the workflow returns, or at once for a completed record, and logs the write. A record persisted at submission finishes once written and fails if the write fails; the client does not keep it. A failed write of client.persist fails only that request. Persisted outputs are read and referenced by every client of the proposal; a reader that relies on the persist request waits for the write and fails with it. Closing waits for pending writes. A restart cancels what nothing persisted needs, runs persisted work whose inputs are written, and fails the rest. The trigger loop persists what a rule names, every output by default. The story fixtures get a fake store and an upgrade that takes over the history; D1 to D3, D6, D7, and F2 take their documented form. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ADR 0005 said a record persisted at submission fails with a write that had not ended at a restart, while its ordered rule runs such a pending record again; the log cannot tell a write in progress from a workflow that has not returned. The sentence now covers writes of completed records only. History's list of accumulators holds the template's values typed, which give the plain request of a state with the pushes. system.md's status line says persisting is implemented over a fake store. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A record persisted at submission finishes once written, so its write needs no event of its own: Finished carries the omitted outputs, and Written is logged only for client.persist. The views hold one write state per output, and _access states the read rule once for submissions, stages, and reads. - client.persist of a pending record no longer delays its completion, and a record lets go of its inputs before its write. - A client reads the values it keeps from memory and the others from the store, so it never gets another client's value. - Closing a client raises naming its client.persist writes that failed, and reading every output raises if one of their writes failed. - A restart runs again a record that wrote but did not finish, and the reasons of records failed at a restart name a lost write or an output not returned. - The plain request of a state comes from the views alone; _check_state returns only why it would be refused. - Rule.persist names outputs or is None for every one. - Story fixtures: upgrade defaults to every toy spec and connect follows it; D2 closes its client before the morning; E1 and E4 read with another client. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A persist request made at submission is part of the record, and its write ends with the record's finish. A client reads persisted values it does not keep from the store. Closing a client raises naming its failed client.persist writes. The store's writes replace, and it may hold values no history names. The restart paragraph follows the ordered rule. D2 closes its client, E1 and E4 read with another, and the upgrade convention follows the fixture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Implements persisting, the third part of the design in #50: nothing is written unless persisted, and the store keeps what is. Stacked on #51, which is stacked on #50.
What changes
local(store=...),Backend(..., store=...)).ess.dispatch.testing.FakeStoreholds values in memory; without a store, persisting is refused.client.submit(..., persist=True | names)andclient.freeze(acc, persist=...)hand the records to the store: the client does not keep them, the record finishes once the outputs named are written, and a failed write fails the record with the write's reason.client.persist(records, *outputs)adds the store next to the client's hold. A failed write fails only that persist request; the client may ask again.upgradetakes over the history and the store after ending the old clients.Why
The service must not keep values for unattended work, and must not write what nobody asked for (ADR 0005). Logging records of states by count gives the restart rule the marker it needs and keeps history linear in the number of pushes (ADR 0004).
ADR 0005 contradicted itself on a record persisted at submission whose write had not ended at a restart. The log cannot tell a write in progress from a workflow still running, so such a record follows the ordered restart rule and runs again; the docs now say so.
Test plan
pytest -n autoin packages/essdispatch (203 passed, 6 xfailed) and packages/essspec (99 passed), several runstests/persist_test.py: persisting at submission,client.persist, failed writes, readers that wait for a write, freezing withpersist=, closing, and the restart rules🤖 Generated with Claude Code