Repository navigation
client cache: group-level configuration (MultiGroupOptions.ClientCache) and Prefixes as RedisKey - #3304
Merged
Conversation
….ClientCache, inherited; a member's own is refused), and Prefixes as RedisKey over a private byte snapshot - MultiGroupOptions.ClientCache / Builder.ClientCache: the one place a group's cache is set. Each member keeps a cache of its own and the group answers from the active one, so members must cache alike or a failover would change what callers get; a member whose ConfigurationOptions.ClientCache is set is refused (at connect and at AddAsync). Plumbed like the group circuit breaker: alongside the configuration, never written into it; a sentinel member gets a clone, since its cache is built with the connection, and a sentinel connection itself never builds a cache. - CacheOptions.Prefixes is IReadOnlyList<RedisKey>: keys are bytes, and a prefix that is not valid UTF-8 had no spelling; a key made with WithKeyPrefix is taken whole. Rendered once to a private byte[][] that both the matcher and the handshake's PREFIX arguments read (no re-encoding on the way out); nothing of the caller's list or arrays is kept, and the getter hands out copies. Existing string call sites compile unchanged. - GetClientCache remark: on a group it is the active member's cache at the time of the call. - Tests: GroupCacheTests (group-level configuration, late joiner, member cache refused), prefix snapshot/bytes/prefixed-key tests. Docs: Failover.md row and section, ClientSideCaching.md "Connection groups", design ledger. Main suite net10.0: 7898 passed, 0 failed, 167 skipped.
…ation.md, and describe Prefixes as RedisKey values copied when set
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.
Two related changes to how a client-side cache is configured.
Group-level
ClientCacheOn a connection group the cache is now set once, on
MultiGroupOptions.ClientCache(andBuilder.ClientCache), and every member inherits it. A member whose ownConfigurationOptions.ClientCacheis set is refused with anArgumentExceptionnaming the member and pointing at the group option, both atConnectGroupAsyncand atAddAsync.Why group-level only: each member keeps a cache of its own (the invalidations that keep it honest arrive on that member's connections), and the group serves reads from whichever member is active. Members that cached differently, or one that did not cache at all, would change what callers get on every failover. One definition inherited by all is how they agree; a per-member override would be a way to disagree.
Plumbing mirrors the group circuit breaker: the options travel alongside the configuration into the multiplexer constructor and are never written into the caller's
ConfigurationOptions. Two decisions taken on the way:CLIENT TRACKINGis not something to negotiate with a sentinel), which closes a latent hazard for anyone who setClientCacheon sentinel options.The
GetClientCache()remark now says what a held view means on a group: the active member's cache at the time of the call.CacheOptions.PrefixesasIReadOnlyList<RedisKey>Keys are bytes; a prefix that is not valid UTF-8 had no string spelling, and a key made with
WithKeyPrefixcan now be given as it is (taken whole, context prefix plus value, which is what the wire sees and what is matched). ExistingPrefixes = ["app:"]call sites compile unchanged via the implicit conversion.The list is rendered once into a private
byte[][]snapshot that both the matcher and the handshake'sPREFIXarguments read, so the local and server-side filters cannot disagree and nothing is re-encoded on the way out. Nothing of the caller's survives: not the list, not the array behind a byte key, and the getter hands out fresh keys over fresh copies, since aRedisKeyover abyte[]returns that array through its explicit conversion. Validation is unchanged: empty and overlapping prefixes are rejected at init.Tests and docs
GroupCacheTests: configuration moved to group level; new tests that every member including a late joiner runs the group's cache and becomes a peer while the callers' options stay untouched, and that a member bringing its own cache is refused at connect and atAddAsync.RespClientCacheTests: prefix snapshot (list, byte array, and getter result all mutated after the fact), arbitrary-byte prefix, prefixed-key rendering.docs/Failover.md(table row and section),docs/ClientSideCaching.md("Connection groups"), design ledger entry.Build green with CI settings. Main suite net10.0: 7898 passed, 0 failed, 167 skipped.