Skip to content

feat: Add Redis Sentinel support for HA#6125

Open
timon0305 wants to merge 4 commits intoreflex-dev:mainfrom
timon0305:feature/redis-sentinel-support
Open

feat: Add Redis Sentinel support for HA#6125
timon0305 wants to merge 4 commits intoreflex-dev:mainfrom
timon0305:feature/redis-sentinel-support

Conversation

@timon0305
Copy link

@timon0305 timon0305 commented Feb 11, 2026

Summary

Closes #5830

  • Adds Redis Sentinel configuration fields to BaseConfig (redis_sentinel_nodes, redis_sentinel_service, redis_sentinel_password, redis_sentinel_db, redis_sentinel_ssl)
  • Updates get_redis() and get_redis_sync() to create Sentinel-backed clients when configured, using redis-py's built-in Sentinel class
  • Updates StateManager.create() to auto-detect Redis mode when Sentinel config is present
  • Updates config validation to accept either redis_url or redis_sentinel_nodes + redis_sentinel_service

Usage

In rxconfig.py:

config = rx.Config(
    app_name="myapp",
    redis_sentinel_nodes="sentinel1:26379,sentinel2:26379,sentinel3:26379",
    redis_sentinel_service="mymaster",
)

Or via environment variables:

REFLEX_REDIS_SENTINEL_NODES="sentinel1:26379,sentinel2:26379" \
REFLEX_REDIS_SENTINEL_SERVICE="mymaster" \
reflex run

Files changed (3)

  • reflex/config.py - Added 5 sentinel config fields, updated validation, added password to sensitive env vars
  • reflex/utils/prerequisites.py - Added _parse_sentinel_nodes(), _get_sentinel_config(), updated get_redis() and get_redis_sync() with sentinel path
  • reflex/istate/manager/__init__.py - Updated StateManager.create() auto-detection to include sentinel config

Notes

  • Backward compatible - defaults to None, existing redis_url behavior unchanged
  • Sentinel takes priority over redis_url when both are configured
  • No changes needed to downstream consumers (StateManagerRedis, TokenManager, etc.) since they receive Redis client objects
  • All config fields support REFLEX_* env var overrides automatically
  • 3548 unit tests passed

Test plan

  • Sentinel node parsing: valid multi-node, single node, whitespace, invalid format, invalid port, empty, IPv6
  • Config fields: existence, defaults, direct setting
  • Config validation: Redis mode requires redis_url OR sentinel_nodes+sentinel_service
  • Sentinel connection path (mocked): async/sync sentinel creation, fallback to redis_url, password/db/ssl support
  • Environment variable overrides: REFLEX_REDIS_SENTINEL_* vars picked up
  • Sensitive env vars: REDIS_SENTINEL_PASSWORD masked in logs
  • StateManager auto-detection: includes sentinel config check
  • Full test suite: 3548 passed

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 11, 2026

Greptile Overview

Greptile Summary

This PR adds Redis Sentinel support for high availability deployments by introducing 5 new configuration fields (redis_sentinel_nodes, redis_sentinel_service, redis_sentinel_password, redis_sentinel_db, redis_sentinel_ssl) and updating the Redis client creation logic to detect and use Sentinel when configured.

Key changes:

  • Config validation now accepts either redis_url OR redis_sentinel_nodes + redis_sentinel_service
  • get_redis() and get_redis_sync() check for Sentinel config first, then fall back to redis_url
  • StateManager.create() auto-detects Redis mode when Sentinel is configured
  • Backward compatible - existing redis_url behavior unchanged

Issues found:

  • Password handling issue: redis_sentinel_password is used for both Sentinel authentication and master authentication, but these typically require different credentials in production Sentinel setups
  • Node parsing accepts empty hostnames (e.g., :26379)
  • Cross-module use of private function _get_sentinel_config()

Confidence Score: 3/5

  • This PR has a critical authentication issue that needs resolution before production use
  • The password handling conflates Sentinel node authentication with Redis master authentication, which could cause connection failures in production Sentinel deployments where these credentials differ. The implementation is otherwise well-structured and backward compatible.
  • Pay close attention to reflex/utils/prerequisites.py - the password logic needs clarification or a second password field

Important Files Changed

Filename Overview
reflex/config.py Added 5 Sentinel config fields and updated validation to accept either redis_url or Sentinel nodes+service
reflex/utils/prerequisites.py Implemented Sentinel support with node parsing and client creation - password handling issue with Sentinel vs master auth, empty host validation needed
reflex/istate/manager/init.py Added Sentinel config check to auto-detection logic - uses private function from another module

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant SM as StateManager
    participant Prereq as prerequisites
    participant Sentinel as Redis Sentinel
    participant Master as Redis Master

    App->>SM: StateManager.create()
    SM->>Prereq: _get_sentinel_config()
    Prereq->>Prereq: Check config.redis_sentinel_nodes
    Prereq-->>SM: Returns sentinel config or None
    
    alt Sentinel configured
        SM->>SM: Set state_manager_mode to REDIS
        SM->>Prereq: get_redis()
        Prereq->>Prereq: _get_sentinel_config()
        Prereq->>Prereq: _parse_sentinel_nodes()
        Prereq->>Sentinel: Create Sentinel(nodes, password)
        Sentinel-->>Prereq: Sentinel instance
        Prereq->>Sentinel: master_for(service, db, password, ssl)
        Sentinel->>Master: Discover master
        Master-->>Sentinel: Master connection
        Sentinel-->>Prereq: Redis client
        Prereq-->>SM: Redis client
        SM->>SM: Create StateManagerRedis
    else redis_url configured
        SM->>Prereq: get_redis()
        Prereq->>Prereq: parse_redis_url()
        Prereq->>Master: Redis.from_url()
        Master-->>Prereq: Redis client
        Prereq-->>SM: Redis client
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Copy link
Collaborator

@masenf masenf left a comment

Choose a reason for hiding this comment

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

the StateManagerRedis is created and bound to the redis instance when the app starts. What is the mechanism for failing over to a different redis instance while the server is running? Seems like we might need some checking in an error path for when the redis connection is unavailable and then request the next master from the sentinal nodes

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support redis sentinel for HA

2 participants