Repository navigation
refactor(work): run pause and resume as one writer job - #4139
Merged
Merged
Conversation
PauseRun and ResumeRun now run the contracts run-control service inside one ExactSqlHandle::transact job over WorkSqliteJobStorage, a Work storage that holds the job transaction and no handle. The frontier read, the workflow journal read and the CAS publication commit together, and the awaiting task parks no native thread. The pause/resume reads and publication move to a WorkRunControlTransitionPort without a Send + Sync bound so the job-scoped storage can implement it. Their bodies, the workflow schema check and the run journal replay are shared between the handle and job paths through RegisteredWorkQuery and a new RegisteredWorkWrite trait. The handle-based transition stays for the workflow fan-out run-control sync, which is still synchronous.
|
Contributor
There was a problem hiding this comment.
🔍 Devin Review: 1 flag
Not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
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.
Summary
Step 5 of the storage redesign (
docs/plans/storage/README.md), second slice. Pause and resume of a Work run now run as one writer job.Before this change, a pause made three separate trips to storage: the run's frontier on a reader, the workflow journal replay through a
begin_deferredwriter transaction, and the compare-and-swap publication in its own interactive transaction. Every trip parked the request thread, which is why Work requests ran underoff_native_worker. NowRegisteredWorkApplicationServicesV1::pause_runandresume_runrun the unchangedWorkRunControlServicedecision insideWorkSqliteStorage::transact. The frontier read, the journal read, the decision and the publication commit together or not at all, and the awaiting task parks no thread.offer_work_blocked_interval_receiptsstill runs after the commit.This is the shape the rest of step 5 follows. The decision stays a synchronous contracts function, and it runs on the writer thread over a storage scoped to that job's transaction.
WorkRunControlTransitionPort(contracts) holds the three methods a transition uses. It has noSend + Syncbound, soWorkSqliteJobStorage, which borrows the job transaction, can implement it. The rest ofWorkRunControlStoragePortis unchanged.WorkSqliteJobStorageholds noExactSqlHandle. A job therefore cannot call back into the writer thread that runs it.RegisteredWorkQuery(now also implemented forExactSqlJobTransaction) and a newRegisteredWorkWrite.synchronize_fan_out_run_controls(synchronous workflow fan-out). It goes when that path migrates.Test plan
work_run_control_jobs::pause_and_resume_awaited_on_a_native_worker_park_no_native_thread(application_suite): pause then resume on a native worker leave the native writer-wait and reader-wait counters unchanged. Putting back the old synchronous call inpause_runfails it (writer waits left 11), and so does the same change inresume_run.work_run_control_storage::a_run_control_job_publishes_with_its_frontier_read_or_not_at_all(rusqlite_suite): a job that publishes and then refuses leaves no control row, and an accepted job commits it. Committing regardless of the verdict fails it.bazel test --config=clippyfor rusqlite-runtimeunit_testandrusqlite_suite, contractsunit_testandcontracts_suite, applicationunit_testandapplication_suite, and daemon-serviceunit_testrustfmt_check_2024for each touched crate//crates/tracedecay:daemon_suite,:mcp_suite,:session_suite,:unit_testin CIRefs #4052