Repository navigation
Conversation
A Stream that stayed open longer than its Retention lost its first Records. The memory Store of `temporalio-streams` makes the same change, so both Stores keep one rule.
A resend of a silent Producer's last batch wrote a second readable copy, and a lower epoch of it wasn't fenced. Without the pruning, the `:producers` key had no reader, so the scripts drop it.
The crate dropped the newest-N read and the safety TTL default, and its Store calls take a StreamRef. The patch script pins the sdk-rust commit with those changes.
The Stream crate's Store calls take no namespace, and its keys hold only the Stream id in the hash tag. The tests that used a namespace to keep runs apart take Stream ids of their own.
A read of a Stream that nobody created now fails at once with NOT_FOUND, so the changelog says so for this runtime.
The API dropped StreamWriter, moved each read item's offset into the item, and marks the fields a Producer must send. The patch script pins the sdk-rust commit with those changes.
The Stream runtime takes a Store now, so the Redis runtime wraps its Store in a LazyStore that connects on the first call. The patch script pins the sdk-rust commit with the typed runtime.
The patch script pins the sdk-rust commit where a bridge holds each writer and drops it.
The API dropped the unknown writer reason, so three reasons after it have new numbers. The patch script pins the sdk-rust commit that has them.
The crate had no test target for the Stream crate's writer suite, so no test covered the writers on Redis.
A comment and the docs used an internal name. An open with no batch no longer needs Redis, and two runtimes in one process don't order the batches of one epoch.
The patch script pins the sdk-rust commit where a retry epoch keeps its fence state in its lane and a write on a closed writer fails as closed.
The patch script pins the sdk-rust commit that has the Workflow Producer comments of the API.
A read gives only Records, so the Redis meta hash no longer keeps `closer` and `cstat`. The pin moves to the sdk-rust commit that has the same API.
The Store name replaces the backend name in the config, the runtime and the tests. The writer suite is gone, and the tests build Producer ids as plain text. The pin moves to the new crate.
The README, the changelog and `docs/redis.md` no longer name a writer. They say that a Producer id is opaque and that a bridge calls `StreamRuntime::call`.
The `p|` field and an epoch key have no run id, so the docs give the caller's rule for the id of a run-based kind. The patch script points at the crate commit with the new suite cases.
This was referenced Nov 13, 2026
The crate's code is the same. Its base now has the API files of temporalio/api#895 with an optional sequence on append.
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.
This PR counts a Stream's Retention from its close in the Redis Store, as a namespace's Retention
does. An open Stream also keeps every Producer's dedupe and fence state.
A Stream that stayed open longer than its Retention lost its first Records. Each append ran
XTRIMon the Records older than the Retention, and the log expired one Retention after the last write.
The log now expires at
exp, so an open Stream keeps every Record. It expires only if the Store config setslast_write_ttl, that long after its last write. A closed Stream still expires one Retention after the close.No append drops a Producer's
p|field by its age either. So a resend of a silent Producer's lastbatch gets the first answer, a read never gets a second copy, and a lower epoch of the Producer
stays fenced. The state goes only with the Stream, at the cost of one 88-byte
p|field for eachProducer that wrote to it.
trimis nowmark_log_gone. It only raisestrimmedwhen a write finds the log gone, as afteran eviction.
pruneand the:producerskey are gone, since nothing else read the key. The write scripts taketwo keys, and a Producer no longer needs
+xtrim,+zadd,+zrangebyscoreor+zrem.scripts/patch-sdk-rust.shbuilds against5a5f856fof Streams crate: combined branch for review moetemp/sdk-rust#228, which makes the samechanges in the memory Store and the shared suites.
closerandcstat, since a read gives only Records and tells of a closewith
done.last_write_ttl, since an open Stream keeps the suites' Recordsuntil it expires.
Two later commits follow the Stream crate's changes of Nov. 10.
last_write_ttlreplaces the safety TTL and has no default. A write with no TTL clears an expirythat an earlier write set, so a Producer needs
+hdeland+persist.StreamRef, as the other calls do.<prefix>:{<stream id>}:meta,:logand:closed,so a Stream id is unique in one Redis and key prefix. An ACL key pattern now scopes a user to a
prefix, and
docs/redis.mdsays so.Two more commits follow the Stream crate's changes of Nov. 11. A read has no
create_wait, a write namesits Producer directly, and each read item carries its own offset. The Redis Store needed no change for
them beyond its pin and its tests.
The last commits follow the crate's new shape of Nov. 11.
LazyStore, which connects on the first call that needs Redis. Soa bridge can build the runtime with Redis down, and the first call then fails with
stream_storage_unavailable.UNKNOWN_WRITERreason, so the three reasons after it have new numbers.The last three commits follow the crate's restart of Nov. 12. The crate now keeps only what answers
the five Stream operations.
tests/writer.rsare gone. A bridge callsStreamRuntime::callwith an operation name and the encoded request.store_namereplacesbackendinRedisStreamConfigand inRuntimeOptions, asStreamRef.storedoes in the API.
p|field takes its bytes as they are.The Store keeps a Producer's fence by kind and id, so the id of a run-based kind must hold its run
id.
docs/redis.mdsays so.with one id, an id of any text, and a close by each Producer kind.