Repository navigation
Conversation
The dedicated pub/sub connection (always under RESP2; under RESP3 unless
SharedSubscriptionConnection is enabled) was opened eagerly as part of
activating every endpoint, so a client that never subscribes to anything
still paid for a second socket per node, and a second reconnect per node
on every failover. Seen on AMR, whose options provider disables the
configuration channel: 3.4.x showed two RESP3 connections where 3.0.x
showed one.
ActivateServer now opens that connection only when there is something to
subscribe to straight away: a configuration channel, or subscriptions that
already exist (and may need to move to this endpoint). Otherwise it is
created on first use, via the existing GetBridge paths; with the default
backlog policy the first SUBSCRIBE queues until it is up.
The connect wait ("second leg") and the maintenance handoff deadline
treated an absent subscription bridge as a disconnected one, which would
have left connects hanging; they now consider a connection that has not
been asked for as not required. The endpoint-state connect log says
"NotRequired" for that case instead of "Disconnected".
Tests: AzureManagedRedisConnectionCount now asserts one connection before
pub/sub and the expected count after; a new test covers the eager case
when a configuration channel is set; two tests that relied on the eager
subscription connection now subscribe first.
* Command coverage ledger and audit skill Adds docs/CommandCoverage.md: every upstream Redis command the library does not expose as a typed API, grouped and with a recorded decision (policy, not applicable, deferred, todo, deprecated, enum-only, implemented). Seeded from a diff of redis/redis src/commands (477 specs, @6a5fee67) against the RedisCommand enum and source; it carries forward the dispositions from #2055 (blocking is policy, Functions and ACL are deferred) and replaces that hand-maintained list. Adds the audit-command-coverage skill and its script, which re-runs the diff on request and reports only what changed: new upstream commands with no decision, ledger rows the code now covers, rows the spec no longer has, and enum members the spec does not know. The script exits non-zero when the ledger needs editing. Closes #2055. * Ledger: CLIENT TRACKING is v4, cluster/COMMAND introspection is administration, CLUSTER SHARDS note corrected * Ledger: CLIENT PAUSE/UNPAUSE are operator tooling, not applicable
…ent server values (#3312) * Object-type metadata for native bitmaps (redis/redis#15331), plus the tokens that diff turned up RedisType gains Bitmap ("bitmap", the TYPE reply for a native roaring bitmap, 8.12) and Gcra ("gcra", already in the server's type-name table). KeyNotificationType gains SetBit (emitted under class $ for string bitmaps and class b for native ones) and the other event names the server emits that the enum lacked: arinsert, armset, arring, arseek, gcra, pfadd, sexpire, spersist, sinterstore, zrangestore, and keymiss (class m, side effect group). Fixes the Copy token: the server has only ever emitted "copy_to", so the "copy" token never parsed and a RedisChannel.KeyEvent(KeyNotificationType.Copy) subscription never fired. The member and its value are unchanged. Both parsers are generated from [AsciiHash]; tests extend the token tables. * Drop Gcra: the type was withdrawn before release, so there is nothing for the token to match * Add sunionstore/sdiffstore events (from the keyspace-notifications docs); drop the history comment on Copy
* Forward the name argument in ConnectionGroupMember's string constructor The string overload chained to the ConfigurationOptions constructor without passing `name`, so every member built from a configuration string (the idiom used throughout docs/Failover.md) was named after its first endpoint by Init() instead of the name the caller gave it. Regression test added. * Parenthesize a Debug-only assertion that trips SA1407 `endSegmentLength == 0 & endSegmentCommitted == 0` in DebugAssertValid sits inside `#if DEBUG`, so CI (Release) never compiles it and never saw the StyleCop error; any local Debug build of RESPite failed with TreatWarningsAsErrors. Introduced by ee47e53 after the StyleCop bump in aa1e5c0.
* Parse unbracketed IPv6 ip:port from the server (#1422) CLUSTER NODES, MOVED/ASK and CLIENT LIST write IPv6 addresses without brackets, i.e. "2a06:4e80:3:a::a:7000". The RFC 3986 parser used for configuration strings reads that as a (valid!) eight-group address with no port, so cluster nodes ended up as "[2a06:4e80:3:a::a:7000]:0" and redirections and client addresses were equally wrong. Add Format.TryParseServerEndPoint for the server's "ip:port" form: when there is no ']' and more than one ':', split at the last colon and require both halves to parse; anything else goes to the existing parser unchanged, so configuration parsing is not touched. Use it at the three sites that receive server-emitted text. The sentinel +switch-master handler gets host and port as separate tokens and was gluing them back together with ':' before parsing; pass them to the (host, port) overload instead. * Parse unbracketed IPv6 in MOVING/SMIGRATED endpoints ParseMigrationEndPoint used the configuration-string parser, so an unbracketed IPv6 address parsed as an address with port 0, which the placeholder check then discarded. Use TryParseServerEndPoint, as the other server-emitted sites do; tests for the MOVING successor and SMIGRATED source/target.
…since 3.4.0 (#3316) * public-api.py: apply *REMOVED* entries at promotion instead of copying them The analyzer records a vanished shipped signature as a *REMOVED* line in the unshipped file. Promotion moved every unshipped line across verbatim, so a promotion after any such change would have left the shipped file with both the dead signature and a *REMOVED* copy of it, and the analyzer would then fail the build on the dead one (RS0017). Promotion now consumes the marker: the named signature is dropped from the shipped file, the marker is not carried over, and a marker that names nothing shipped is an error. A *REMOVED* line already sitting in a shipped file is also reported. The "+N promoted" note gains "-N removed", and an unshipped file holding only removals is still emptied. * Promote the shipped API surface: everything since 3.4.0 eng/public-api.py --promote. Fifty-two StackExchange.Redis entries (the lag-aware availability surface, FailbackHealthCheck, HealthCheckProbeScope, the 8.12-independent RedisType and KeyNotificationType tokens) and the net6.0 SetUserPemCertificate overload move to shipped; the three parameter renames from #3296 (muxer -> multiplexer on the Azure providers' AfterConnectAsync, other -> obj on RESPite AsciiHash.Equals) are applied rather than copied. Every unshipped file is now empty.
* Split third-party notices out of LICENSE so GitHub detects MIT The LICENSE file carried ~1.1KB of third-party notes after the MIT text, which drops it below licensee's similarity threshold; GitHub reports the repo license as "Other" (SPDX NOASSERTION). Keep LICENSE as the bare MIT text and move the notes, verbatim, to THIRD-PARTY-NOTICES.md. * Correct the third-party notices - Redis: BSD-3 only through 7.2; RSALv2/SSPLv1 from 7.4, AGPLv3 added in 8.0; point at redis.io/legal/licenses (the old /topics/license URL now redirects to the docs landing page). - redis-doc: repo is archived under redis/redis-doc; note that redis/docs, its successor, is CC BY-NC-SA for newer content. - Drop the Redis-64 and BookSleeve notes: neither is part of the development solution any more. - Add the code actually incorporated from other projects (dotnet/runtime, dotnet/corefx, aspnet/BasicMiddleware) and the test-only redis-sharp copy, none of which the old notes mentioned.
…d IPv6, batch profiling, Bitmap/keyspace tokens, coverage ledger Ports onto the new core, by intent where the old core's files are gone: - #3310 lazy subscription connection: ActivateServer now dials the subscription socket only when RequiresEagerSubscriptionConnection says there is something for it to do (the configuration channel, or existing subscriptions); DialSubscriptionSocketForConfigurationChannel becomes DialSubscriptionSocketIfRequired with the broadened guard. The endpoint log distinguishes a socket nobody asked for (NotRequired) from a down one, via HasDedicatedSubscriptionConnection. - #3307 unbracketed IPv6: Format.TryParseServerEndPoint merged clean; the old ResultProcessor MOVED/ASK site is now Contexts/RespRedirect, patched to match, and the ROLE reply parse in RespHandshake stops gluing host:port (the sentinel mistake, found at two more sites v4 grew). - #3313 batch profiling (#2175): the ported ProfilingTests.Batch FAILED on this core too - a batch bypasses Dispatch, where single sends start their records - so SendRun now starts the same record per operation on the batch path, and a batched operation carries its Command identity. A transaction's run stays unprofiled, as it always was. - #3314 ConnectionGroupMember name fix merged clean (its CycleBuffer half had already arrived via ce5a8cd). - #3316 public-api promotion: the 3.4.29 surface moved to Shipped; the 38 Unshipped entries that promotion made duplicates are dropped, and the v4-only surface stays unshipped. - #3311/#3312/#3317 merged clean (coverage ledger + audit skill, RedisType.Bitmap + keyspace tokens, LICENSE split).
This branch has not been deployed
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.
Brings v4 up to
main@02b9ce4e(the 3.4.29 release). Four of main's eight commits merged clean (#3311 coverage ledger + audit skill, #3312 RedisType.Bitmap + keyspace tokens, #3314 ConnectionGroupMember name fix, #3317 LICENSE split); the rest were ported by intent onto the new core. Merge with a merge commit, not a squash — the merge carries the ancestry record, so no separate "Record main@…" commit is needed unless this gets squashed.Ported by intent
DialSubscriptionSocketForConfigurationChannelno-ops without a configuration channel. The port completes it:ActivateServergates onRequiresEagerSubscriptionConnection(configuration channel, or existing subscriptions that may need to move to this endpoint), the dial method becomesDialSubscriptionSocketIfRequiredwith the broadened guard (AnySubscribed(), matching the RESP3-downgrade path's own condition), and the endpoint-state log saysNotRequiredfor a socket nobody has asked for, via a newHasDedicatedSubscriptionConnectionprobe — asking never dials. Main'sIsSubscriberConnectedOrNotRequiredis re-expressed over the connection manager rather than bridge fields.Format.TryParseServerEndPoint+ call sites merged clean (ClientInfo, ClusterConfiguration, sentinel, MaintenanceNotificationReader — rename detection carried the oldPhysicalConnection.Maintenancehunk across). The oldResultProcessorMOVED/ASK site is nowContexts/RespRedirect.cs, patched to match. Two v4-only sites main never had were fixed the same way:RespHandshake's ROLE-reply parsing gluedhost + ":" + port, which turns an unbracketed IPv6 host into an address with no port — it now uses the (host, port) overload, as main's sentinel fix did.ProfilingTests.Batchfailed on v4 too — the new core has the same bug by a different route: a batch bypassesDispatch, where single sends start their profiling records.SendRunnow starts the same record per operation on the batch path (same database rule: the command's database,-1for database-free commands), and a batched operation now carries itsCommandidentity. A transaction's run stays unprofiled, as it always was.Shippedvia the merge; the 38Unshippedentries that the promotion made duplicates (LagAware*, FailbackHealthCheck, AfterConnectAsync rename, …) are dropped, and the v4-only surface stays unshipped. Theeng/public-api.pyREMOVED-at-promotion change merged clean.Not ported (nothing to port)
AttachProfiling(Message, ServerEndPoint)and theRedisBatch/ResultProcessoredits die with the old core; their intent is theSendRun/RespRedirectchanges above.Follow-ups
docs/CommandCoverage.mdwas generated against main's surface; re-running theaudit-command-coverageskill on v4 (where e.g. HOTKEYS/XCFGSET exist) will shrink the gap list.