Repository navigation
Conversation
moetemp
force-pushed
the
moe/brook/review/s4-backends
branch
from
October 26, 2026 00:14
b146c64 to
ce8bd6d
Compare
moetemp
force-pushed
the
moe/brook/review/s5-client-reads
branch
from
October 26, 2026 00:14
252b606 to
b70af4e
Compare
moetemp
force-pushed
the
moe/brook/review/s4-backends
branch
from
October 26, 2026 02:08
ce8bd6d to
e453c8e
Compare
moetemp
force-pushed
the
moe/brook/review/s5-client-reads
branch
2 times, most recently
from
October 26, 2026 08:44
50134b6 to
6636d64
Compare
moetemp
force-pushed
the
moe/brook/review/s4-backends
branch
2 times, most recently
from
October 27, 2026 09:07
0d0ab14 to
9f62387
Compare
moetemp
force-pushed
the
moe/brook/review/s5-client-reads
branch
2 times, most recently
from
October 27, 2026 09:17
86ae5d2 to
c774176
Compare
moetemp
force-pushed
the
moe/brook/review/s4-backends
branch
from
October 27, 2026 09:17
9f62387 to
9afffa1
Compare
moetemp
force-pushed
the
moe/brook/review/s5-client-reads
branch
2 times, most recently
from
October 28, 2026 07:54
fe0790c to
62769cb
Compare
moetemp
force-pushed
the
moe/brook/review/s4-backends
branch
from
October 28, 2026 07:54
36ed7f5 to
c0c0a86
Compare
`Client.create_stream` creates a Stream or gets the one that exists, and `Client.stream` binds one with no call. A `ClientStream` in a query result uses the client that made the query. A read yields Records, the Superseded items that withdraw earlier Records, and the close.
moetemp
force-pushed
the
moe/brook/review/s5-client-reads
branch
from
October 28, 2026 08:05
62769cb to
7265a04
Compare
A closed or expired Stream fails the create, and a close sends only its failure, which sets the close status. A read skips an item kind that it doesn't know.
The proposed API has one handle type in every context. A handle passes each call to the calls of the context where it runs. In client code that's the client that made the handle or the client that decoded it. `Client.get_stream_handle` replaces `Client.stream`, and `publish` starts the write and returns its future.
# Conflicts: # temporalio/common/__init__.py # temporalio/common/_streams/_handle.py
Stream and Stream reads.
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.
What was changed
This PR adds
temporalio.client.Stream, which makes the Stream calls outside Workflow code, withClient.create_stream,Client.get_stream,Client.to_streamand Stream reads (Subscription).Client.create_streamis create-or-get by Stream id. On a Stream that exists, it ignores the options and returns that Stream, and on a closed one it raisesStreamClosedError. It takes an optional backend name, so it doesn't depend on the Store.Client.get_stream(definition, *, id, backend=None)makes no call. Reads decode each Record with the definition's payload type.Client.to_stream(handle, *, payload_type=None)gives theStreamof a handle that came as data, such as a query result. It makes no call. Reads decode each Record as a JSON value, unlesspayload_typeis given.stream.handlegives the data to pass on.publishstarts the write at the call and returns a future. The writes of oneStreamkeep the order of the calls. A write error that no caller got raises at the next call of theStream, andclosecloses first, then raises it.rpc_metadataandrpc_timeoutare keyword-only onpublish,subscribe,get_offsetandclose.closeon a Workflow's Stream raisesStreamNotOwnerErrorwith no call, and so doesasync withat__aenter__.Supersededitems that withdraw earlier Records, andClosedlast. It long-polls and starts at an offset, atENDor at the newestlastRecords. It matches each item on theoneofof data, superseded and close. The long poll's loop, which carries the offset across empty pages, is here.Supersededitem can withdraw, as runs of consecutive offsets. A batch has consecutive offsets, so a read of a million batched Records keeps almost nothing, and a read of a million single Records keeps about 17 MB, not 44 MB._convert.pyand_writer.pyare here and not in S3 and S4, since their first users are here.Depends on S4 (#374). No changelog fragment, since S9 has the Streams entry.
Part of the Brook review series.
Why?
This is the client half of the API, which S6 runs on Redis and in memory.
Checklist
poe lint,poe gen-docsandpytest tests/contrib/streams.