Skip to content

DOC-7177 Document ioredis smart client handoffs (SCH) [PARKED] - #4252

Open
andy-stark-redis wants to merge 2 commits into
mainfrom
DOC-7177-ioredis-sch
Open

andy-stark-redis wants to merge 2 commits into
mainfrom
DOC-7177-ioredis-sch

Conversation

@andy-stark-redis

@andy-stark-redis andy-stark-redis commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Documents smart client handoffs (SCH) for ioredis, added in v6.1.0-beta.1 by redis/ioredis#2165.

  • content/develop/clients/ioredis/connect.md: new Connect using Smart client handoffs (SCH) section (same anchor as the other clients).
  • content/develop/clients/sch.md: ioredis row in the support table (v6.1.0 standard routing, no OSS Cluster API) and a relatedPages entry.

Warning

Do not merge. The docs cite ioredis v6.1.0, which is still in beta. Merge only after a stable v6.1.0 release contains #2165 and /unpark has reconciled the page.

No bannerText was added: the SCH section is one section of an otherwise-released page, and its version note already says v6.1.0 is required.

Park manifest

Ticket: DOC-7177
Parked at: 2026-10-13
Trigger to pick up: a non-prerelease ioredis tag v6.1.* exists and #2165's merge commit d8ae3cb24c534e77b2c2df2f542cbf4789d758fe is an ancestor of it (gh api repos/redis/ioredis/compare/d8ae3cb24c534e77b2c2df2f542cbf4789d758fe...<tag> --jq '{status, behind_by}' → behind_by: 0). The release is cut from main, which #2165 targets.
Labels: parked, do not merge yet

Pinned sources (state observed at park time)

Source State at park time Re-fetch
redis/ioredis#2165 closed, merged 2026-10-12T08:46:34Z; merge d8ae3cb2; head d02cdc7a; base main; milestone none; updated 2026-10-12T15:48:05Z gh api repos/redis/ioredis/pulls/2165 --jq '{state, merged, merge_sha: .merge_commit_sha, head_sha: .head.sha, base: .base.ref, updated_at}'
Tag v6.1.0-beta.1 commit d9a0b9a3; prerelease; contains #2165 (behind_by: 0). Latest stable: v6.0.0 gh api repos/redis/ioredis/releases --jq '.[0:5][] | "\(.tag_name) prerelease=\(.prerelease)"'
lib/redis/RedisOptions.ts @ beta.1 blob 7a7da5bd gh api "repos/redis/ioredis/contents/lib/redis/RedisOptions.ts?ref=<tag>" --jq .sha
lib/maintNotifications/index.ts @ beta.1 blob 9bde14d2 same, path swapped
lib/index.ts @ beta.1 blob 41dba873 same, path swapped
lib/Redis.ts @ beta.1 blob 2da6717c same, path swapped
lib/cluster/ConnectionPool.ts @ beta.1 blob 4862fc41 same, path swapped

If a blob SHA is unchanged at the stable tag, the identifiers that file supports still hold.

Observed shape the page assumes

Semantics — HIGH (read from the installed ioredis@6.1.0-beta.1 build, not the release notes):

  • SCH is on by default: maintNotifications defaults to "auto", and RESP3 has been the default protocol since v6.0.0 (RedisOptions.js: protocol: 3). protocol: 2 disables it.
  • Cluster connections are excluded: cluster/index, ConnectionPool, ClusterSubscriber and ShardedSubscriber all force maintNotifications: "disabled".
  • Sentinel, Unix socket (path), custom Connector, subscriber and monitor connections still register and get relaxed timeouts on MIGRATING/FAILING_OVER/MOVING. Only the handoff is skipped (canHandoffConnection() / resolveMaintConfiguredEndpoint() in Redis.js), so they reconnect normally.
  • "auto" endpoint type picks internal/external by private-address check, and an FQDN when TLS is on (resolveMaintEndpointType in maintNotifications/index).
  • A handoff invalidates WATCH; the pending EXEC rejects with WatchError.

Identifiers — MEDIUM (released beta, but pre-GA names can still move). Each was seen in the shipped .d.ts / .js named:

  • maintNotifications: "auto" | "enabled" | "disabled", default "auto" (redis/RedisOptions.d.ts; union MaintNotifications in maintNotifications/index.d.ts)
  • maintEndpointType: "auto" | "internal-ip" | "internal-fqdn" | "external-ip" | "external-fqdn" | "none", default "auto" (same files; union MaintEndpointType)
  • maintRelaxedCommandTimeout: number, default 10000 (redis/RedisOptions.d.ts)
  • maintRelaxedSocketTimeout: number, default 10000 (redis/RedisOptions.d.ts)
  • CommandTimeoutDuringMaintenanceError: exported from index.d.ts; .name matches the class name
  • SocketTimeoutDuringMaintenanceError: as above
  • WatchError: exported from index.d.ts, extends AbortError
  • protocol default 3 (redis/RedisOptions.js)

Changelog and source disagree in one place: the option JSDoc calls the errors CommandTimeoutDuringMaintenance / SocketTimeoutDuringMaintenance, but the exported classes carry an Error suffix. The docs use the exported names.

Re-check checklist

  • HIGH RISK: cluster still disabled at the stable tag. If OSS Cluster API support lands, update the sch.md cell (currently -) and the version note in ioredis/connect.md.
  • Every identifier in the list in "Observed shape the page assumes" still matches at the stable tag.
  • The stable version number: if GA ships as something other than v6.1.0, update both files.
  • Sentinel/socket/subscriber/monitor still get relaxed timeouts without a handoff (re-read canHandoffConnection and resolveMaintConfiguredEndpoint).
  • WatchError behavior and message unchanged (errors/WatchError).
  • Re-run the type-check: scratch project, npm install ioredis@<stable>, tsc --noEmit --strict --skipLibCheck over the section's example (with host/port placeholders filled in), plus a @ts-expect-error invalid maintEndpointType value. Without --skipLibCheck, the library's own .d.ts fails on the untyped redis-errors module at beta.1 — check whether that's been fixed.
  • Open question: the ioredis:maintenance diagnostics_channel (DataHandler.js publishes each raw notification) is deliberately undocumented, matching the other clients' SCH sections. Revisit if the release notes promote it.
  • Not verifiable locally: a live handoff needs a Redis Cloud or Redis Software maintenance event.

On unpark, then

Run /unpark <this PR>. It reconciles the docs against the settled source and owns the closing sequence; the do not merge yet guard holds until /finalize completes.

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only changes with no runtime or security impact; merge is gated on stable ioredis v6.1.0 per the PR park manifest.

Overview
Documents Smart client handoffs (SCH) for ioredis (v6.1.0+), aligning it with the other Redis client connect guides.

The ioredis connect page gets a new Connect using Smart client handoffs (SCH) section with a connection example and option reference (maintNotifications, maintEndpointType, relaxed timeouts, RESP3, cluster/Sentinel limitations, WatchError, and PrivateLink/PSC notes). Minor fixes on the same page: front matter description corrected to Node.js/JavaScript, and the TLS example uses readFileSync consistently for the CA cert.

The SCH overview page links to the new anchor and adds an ioredis row (standard routing v6.1.0; OSS Cluster API not supported).

Reviewed by Cursor Bugbot for commit 2059dc6. Bugbot is set up for automated code reviews on this repo. Configure here.

Add a "Connect using Smart client handoffs (SCH)" section to the ioredis
connect page (same anchor as the other clients) and an ioredis row to the
SCH support table on sch.md. Written against ioredis v6.1.0-beta.1
(redis/ioredis#2165); parked until stable v6.1.0 ships.

Verified against the installed ioredis@6.1.0-beta.1 package, not the
release notes: option names, defaults, and the MaintNotifications /
MaintEndpointType unions come from the shipped .d.ts; the example
type-checks (tsc --strict --skipLibCheck; without skipLibCheck the
library's own .d.ts fails on untyped redis-errors, an upstream gap).
No live handoff was tested: that needs a Redis Cloud/Software
maintenance event.

Scope facts from built/Redis.js and MaintenanceManager.js:
- Cluster connections (ConnectionPool, subscribers, cluster/index) force
  maintNotifications "disabled", so the OSS Cluster API cell is "-".
- Sentinel, Unix socket, custom Connector, subscriber and monitor
  connections still register and open the relaxed-timeout window on
  MIGRATING/FAILING_OVER/MOVING; only the handoff is skipped
  (canHandoffConnection / resolveMaintConfiguredEndpoint return
  false/null) and they reconnect normally. A WebFetch summary of
  Redis.ts claimed these were not registered at all - wrong.
- RESP3 is the default since v6.0.0 (RedisOptions.js protocol: 3), so
  unlike node-redis the example omits a protocol option.
- Error classes are exported as CommandTimeoutDuringMaintenanceError and
  SocketTimeoutDuringMaintenanceError (.name matches). The option JSDoc
  says "CommandTimeoutDuringMaintenance"; docs use the importable name.
- A handoff invalidates WATCH and EXEC rejects with WatchError
  ("Retry it with a fresh WATCH") - not documented for node-redis.

Rejected: documenting the "ioredis:maintenance" diagnostics_channel
(DataHandler.js publishes each raw notification on it). No other
client's SCH section documents observability hooks; add if asked.

Unpark watch: re-diff built/redis/RedisOptions.d.ts,
built/maintNotifications/index.d.ts and built/index.d.ts at the v6.1.0
tag; cluster support landing before GA would change the table cell and
the version note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andy-stark-redis andy-stark-redis added do not merge yet parked PR speculatively added based on pre-release info. Check validity when release goes ahead. labels Oct 13, 2026
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7177

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

Found 6 related items from repository history (1 new this commit):

Memory updated at 2059dc6

@github-actions

Copy link
Copy Markdown
Contributor

@andy-stark-redis andy-stark-redis self-assigned this Oct 13, 2026
@andy-stark-redis andy-stark-redis added the clients Client library docs label Oct 13, 2026
…nits

- Frontmatter description said "Python"; now "Node.js/JavaScript",
  matching ioredis/_index.md.
- TLS example mixed readFileSync and fs.readFileSync; all three now use
  bare readFileSync, matching the node-redis connect page.
- SCH relaxed-timeout options state "in milliseconds" explicitly
  (confirmed by the RedisOptions.d.ts JSDoc).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clients Client library docs do not merge yet parked PR speculatively added based on pre-release info. Check validity when release goes ahead.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant