Skip to content

[Brook] Wrote Workflow Records through Local Activities. - #357

Closed
moetemp wants to merge 11 commits into
moe/brook/v4/p29-writer-resourcefrom
moe/brook/v4/p30-workflow-local-writes
Closed

moetemp wants to merge 11 commits into
moe/brook/v4/p29-writer-resourcefrom
moe/brook/v4/p30-workflow-local-writes

Conversation

@moetemp

@moetemp moetemp commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

This PR writes Workflow Records through one Local Activity per call.

What changed?

create_stream, publish and close in a Workflow each run one Local Activity (__temporal_streams_create, __temporal_streams_append, __temporal_streams_close). The plugin registers the three activities.
Writes to one Stream run in order. A failed write raises at the await, or fails the Workflow Task for the _nowait forms. publish returns the last offset.
The run drains its writes before it returns or continues as new, and closes its Streams at the end of the chain.
A write keeps the Workflow Task in its Producer epoch, so a Local Activity retry in the same task dedupes, and a later task withdraws what a failed task wrote. A retry run withdraws the failed run on its first write to each Stream. A create names the run chain as the Stream owner.
The Workflow call buffer, the Activation flush, the durable_writes options and the unused on_workflow_activation_complete plugin hook are gone.
The crate pin moves to s20 f3c74d24, and the sdk-core submodule moves to Brook c6 32ba79d6. Together they drop the Workflow write buffer and the Workflow Task hooks, and add the run's task history to a Local Activity task. The bridge's debug test extension loses its hook counters, and so does tests/worker/test_extension.py.
S110: every Local Activity write (the Workflow writes and a user Local Activity's writer) sends the run's last completed Workflow Task and its failed tasks, from the new activity.Info.workflow_task.previous_started_event_id and failed_tasks. So the run's next write to a Stream withdraws what Local Activities wrote there in tasks that never completed. The Superseded docstring states the limit: a Stream that the run never writes again keeps those Records.

Why?

A Local Activity gives each write a recorded result, so replay does not write again and a write error reaches the caller. The run buffer and its flush on Workflow Task completion are no longer needed.

How did you test it?

New tests cover a write to a closed Stream and to a missing Stream, ordered concurrent publishes with a Replayer that shows no write on replay, a retried append that goes in once, a user Local Activity that runs again after a failed Workflow Task and withdraws its first attempt, and a failed task's Local Activity that the retry task skips, whose Records the next write withdraws. The streams suite passes on the memory and Redis backends, and poe lint is green.

🤖 Generated with Claude Code

@moetemp

moetemp commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

Closing as stale. This layer is folded into the v5 tip, #365, and the upstream review uses a fresh series instead. Plan: https://www.notion.so/4048fc567738814990b7c796ac28fe3f

@moetemp moetemp closed this Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant