Skip to content

[Brook] Flushed a Workflow's Stream calls around each Workflow Task completion. - #20

Closed
moetemp wants to merge 7 commits into
moe/brook/v3/s3-stream-servicefrom
moe/brook/v3/s4-workflow-flush
Closed

moetemp wants to merge 7 commits into
moe/brook/v3/s3-stream-servicefrom
moe/brook/v3/s4-workflow-flush

Conversation

@moetemp

@moetemp moetemp commented Oct 21, 2026

Copy link
Copy Markdown
Owner

What changed?

This PR adds the Workflow path. Lang calls BufferWorkflowCalls at the end of each Activation. The crate's WorkflowTaskInterceptor writes the run's creates and appends in before_complete, as the run's Producer wf:<run id> with the task's epoch, previous_completed_task and failed_tasks. It sends the closes in the background after after_complete accepts. A close from auto_close goes out only when the completion closes the run. The flush splits at the batch limit and drops oversize Records and Records for a Stream that someone else closed, with stream_records_dropped. durable_writes runs WAIT. DrainCloses waits for the closes at shutdown.

Why?

Activations and Workflow Tasks are not one to one, so the data goes out once per task. Closes wait for acceptance, so a refused completion never closes a Stream. Core holds the run's next task until after_complete returns, so the close retries run in the background.

How did you test it?

STREAMS_REQUIRE=redis cargo test -p temporalio-streams --test workflow drives the buffer call and the hooks as Core calls them, on standalone and cluster Redis.

  • Unit Tests
  • Staging
  • End to End Tests

Activations and Workflow Tasks are not one to one, so the crate keeps each run's calls and writes them once per task in before_complete. Closes wait for an accepted completion and go out in the background, so they never hold the run's next task.
… time.

A failure that the server retries, or a cron run, goes on with the Run Chain, so lang's chain_continues keeps its auto close out. A task with no started time fails its flush, since its epoch could collide with a dropped speculative task. Durable flushes write and wait on their own connection.
A Local Activity heartbeat completion comes at 80% of the task timeout, so the fixed 200 ms margin ate all the time left and failed the flush. The margin is now at most a quarter of the time left, and a mock-Worker test covers the heartbeat flush end to end.
Lang may cancel DrainCloses at shutdown, and the tracker then stayed closed. The tests also check that calls after a drain, or after a dropped one, still answer.
@moetemp

moetemp commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

Closing as stale. This layer is folded into the v5 tip, #41, 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