Skip to content

Add Redis Sentinel support to prefect-redis#22377

Open
fatih-acar wants to merge 1 commit into
PrefectHQ:mainfrom
fatih-acar:feat/redis-sentinel-on-22211
Open

Add Redis Sentinel support to prefect-redis#22377
fatih-acar wants to merge 1 commit into
PrefectHQ:mainfrom
fatih-acar:feat/redis-sentinel-on-22211

Conversation

@fatih-acar

Copy link
Copy Markdown
Contributor

Supersedes #22248, which targeted the prefect-redis-cluster-client-foundation branch from #22211; that branch has since merged to main, auto-closing the old (draft) PR. This re-opens the work against main.

This PR adds native Redis Sentinel support to prefect-redis, building on the Redis Cluster URL groundwork merged in #22211. Cluster URLs stay detection-only (gated behind NotImplementedError) exactly as #22211 left them; this PR enables the redis+sentinel:// and rediss+sentinel:// schemes across every connection point: the server messaging client, RedisLockManager, the RedisDatabase block, and the Docket services URL.

Details
  • New prefect_redis.connection module — a shared URL parser (parse_redis_url) and client builder (build_redis_client) that resolve the current master through the listed Sentinel daemons and follow failover automatically. Data-node (master) connections get pinned TCP keepalive so a silently-dead master is noticed promptly while Sentinel completes failover.
  • client.py dispatches redis+sentinel:// URLs to the Sentinel builder while leaving Add Redis Cluster URL and key groundwork #22211's cluster NotImplementedError gate intact.
  • RedisLockManager and RedisDatabase accept a connection_url that is authoritative over the scalar host/port fields; RedisDatabase round-trips Sentinel URLs through from_connection_string and block_info.
  • PREFECT_SERVER_DOCKET_URL documents the Sentinel schemes; the pydocket floor is bumped to >=0.22.0 for its Sentinel URL support.

URL grammar follows the redis-sentinel-url convention:

redis+sentinel://[user:pass@]sentinel-a:26379,sentinel-b:26379/<master-name>[/<db>][?params]

The Sentinel schemes accept a comma-separated member list and a master group name; sentinel_username, sentinel_password, sentinel_ssl, sentinel_tls_insecure, and sentinel_tls_ca_file query params configure the Sentinel daemon connections separately from the data nodes.

Testing

  • Full prefect-redis suite passes (214 tests, incl. 46 new connection/integration tests).
  • Verified against a real Sentinel HA topology in Docker (master + 2 replicas + 3 Sentinels, quorum 2): SIGKILL the master and the async/sync connection clients, get_async_redis_client, and RedisLockManager all automatically follow the Sentinel-promoted replica; data written before the crash survives via replication; the restarted old master rejoins as a replica.
  • Verified the RedisDatabase block against a real Prefect server: block saved/loaded through the REST API, flow runs recorded COMPLETED, and read_path/write_path survive a master failover (Prefect task retries ride the promotion window).

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 989a3144b0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


def is_sentinel_url(url: str) -> bool:
"""Return True if the URL uses a Redis Sentinel scheme."""
return urlparse(url).scheme in SCHEME_SENTINEL

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect Sentinel URLs without validating the netloc

When the Sentinel member list includes an IPv6 host alongside another member (for example redis+sentinel://s1:26379,[::1]:26379/mymaster), urllib.parse.urlparse raises ValueError: Invalid IPv6 URL before the new tolerant parse_redis_url path can run. That makes get_async_redis_client reject a URL shape that _split_connection_url and the parser tests explicitly support; detect the scheme without stdlib netloc validation or reuse the shared splitter here.

Useful? React with 👍 / 👎.

raise RedisUrlError(
f"Invalid database index {segment!r} in connection URL: {redact_redis_url(url)}"
) from exc
if not 0 <= db <= 15:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow configured Redis database indexes above 15

When a Redis or Sentinel deployment is configured with more than the default 16 logical databases, URLs such as redis+sentinel://s1:26379/mymaster/16 are valid for the server/redis-py but this parser rejects them before connecting. Because this parser now gates the new connection_url paths, those deployments cannot select their configured database; only reject non-integer or negative values and let Redis report an unavailable DB.

Useful? React with 👍 / 👎.

@codspeed-hq

codspeed-hq Bot commented Jun 25, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 8 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing fatih-acar:feat/redis-sentinel-on-22211 (4b28891) with main (5bbc9f5)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

Build on the Redis Cluster URL groundwork merged in PrefectHQ#22211 to add native
Redis Sentinel support. Cluster URLs stay gated (detection-only) exactly as
in PrefectHQ#22211; this change enables the redis+sentinel:// and rediss+sentinel://
schemes across every connection point: the server messaging client, the
RedisLockManager, the RedisDatabase block, and the Docket services URL.

- New prefect_redis.connection module: a shared URL parser (parse_redis_url)
  and client builder (build_redis_client) that resolve the current master
  through the listed Sentinel daemons and follow failover automatically.
  Data-node connections get pinned TCP keepalive so a silently-dead master is
  noticed promptly while Sentinel completes failover.
- client.py dispatches redis+sentinel:// URLs to the Sentinel builder while
  leaving PrefectHQ#22211's cluster NotImplementedError gate intact.
- RedisLockManager and RedisDatabase accept a connection_url that is
  authoritative over the scalar host/port fields; RedisDatabase round-trips
  Sentinel URLs through from_connection_string and block_info.
- Document the Sentinel schemes on PREFECT_SERVER_DOCKET_URL and bump the
  pydocket floor to >=0.22.0 for its Sentinel URL support.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fatih-acar fatih-acar force-pushed the feat/redis-sentinel-on-22211 branch from 989a314 to 4b28891 Compare June 30, 2026 08:19
@fatih-acar

Copy link
Copy Markdown
Contributor Author

hi team, any chance this gets accepted? it's an easier implementation than redis cluster, so hopefully it's not too much to review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1 participant