Skip to content

[Brook] Made the runtime a client object and shared Producer writers. - #39

Closed
moetemp wants to merge 7 commits into
moe/brook/v4/s21-store-takeoversfrom
moe/brook/v4/s22-client-objects
Closed

moetemp wants to merge 7 commits into
moe/brook/v4/s21-store-takeoversfrom
moe/brook/v4/s22-client-objects

Conversation

@moetemp

@moetemp moetemp commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

What changed?

This PR makes the Stream runtime a plain object that the bridge builds per client, and shares one writer per Producer.

  • S123: StreamExtension has no Core trait. A bridge calls StreamExtension::call(method, bytes), and an error has code() and details(). The crate drops temporalio-sdk-core and pins temporalio-common at sdk-rust Brook c7 b565c433.
  • S120: the handles of one Producer epoch on one Stream share one writer. OpenWriter adds a handle, CloseWriter or the new FreeWriter releases one, and the last one drops the writer. StreamExtension::free_writer releases with no wait, for a finalizer.
  • S120, bug 8: every writer takes its sequence from one counter per process, so a reopened writer goes on above its earlier batches with no map of closed writers.
  • S120: ids::named_client_producer_id makes client:<name>, a Producer id that a caller keeps across restarts. With the caller's epoch in attempt, a new incarnation fences the earlier one.
  • S125: every Store and service case says its guarantee in its comment and runs on every backend that gives what it needs (Needs), so Jetty's native Store joins the same suites.

Why?

Core only passed the runtime through to lang, and Dan's bridge shows the crate needs no Core hook. A ClientStream handle's writer went only with a Stream close, and the closed-writer map grew for the life of the process.

A client Producer's newer epoch fences its earlier epochs but writes no Superseded item and withdraws nothing (S120), since a restarted client's earlier Records are real messages. The Redis script, the memory Store and the reader rule agree, and testdata/withdrawals.json has the case. The withdrawal rule stays for Workflow, Local Activity and Activity Producers.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

The suite runs on a standalone Redis 8.10, a three-primary cluster and the memory Store. New cases show two handles sharing a writer until the last one lets go, and a named client fencing its earlier self. cargo fmt --check and cargo clippy --workspace --tests -D warnings pass, also with --no-default-features --features tls-aws-lc.

Core only passed the runtime through to lang. The bridge builds it per client, as Dan's bridge does, so the crate drops sdk-core and pins sdk-rust c7.
A handle's writer went only with a Stream close, and closed writers' sequences stayed for the life of the process. A process-wide sequence needs no such record, and a named client Producer lets a caller fence its earlier self.
@moetemp moetemp changed the title [Brook] Made the runtime a client object and shared writers per Producer. [Brook] Made the runtime a client object and shared Producer writers. Oct 23, 2026
The protos still named a generic extension call, which Core no longer has.
A case runs on every backend that gives what it needs, so the native Store can join the suite where its guarantees hold (S125). Each case's comment says its guarantee.
The server gives the item its own offset, where Redis shares one entry. The order is the guarantee, not the shared offset.
A restarted client's earlier Records are real messages, not a failed attempt's (S120). The withdrawal rule stays for Workflow, Local Activity and Activity Producers, and the shared vectors have the client case.
@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