Skip to content

Add Redis infrastructure and state management#180

Merged
RafaelPo merged 2 commits intomainfrom
feat/redis-infrastructure
Feb 21, 2026
Merged

Add Redis infrastructure and state management#180
RafaelPo merged 2 commits intomainfrom
feat/redis-infrastructure

Conversation

@RafaelPo
Copy link
Contributor

Summary

PR 2 of 5 in the HTTP transport split (follows #179).

  • redis_utils.py: Redis client factory with Sentinel support, exponential backoff retry, health checks, and build_key() helper with colon-sanitization to prevent key injection
  • state.py: ServerState dataclass with Redis-backed storage for task tokens, poll tokens, result metadata, page previews, and CSV results — all with TTLs, no in-memory dicts, fully multi-pod safe
  • Test infrastructure: Real Redis tests via redis-server on port 16379 (session-scoped fixture, flushed between tests), plus CI redis-server installation step
  • Dependency: Added redis>=5.0.0 to pyproject.toml

Multi-pod safety

All mutable shared state goes through Redis — no module-level dicts or process-local caches. Sentinel support is included for production HA. Connections use retry with exponential backoff and periodic health checks.

Test plan

  • test_redis_utils.pybuild_key helper and create_redis_client factory (direct + Sentinel modes)
  • test_state_redis.py — Round-trip tests for all Redis-backed ServerState methods (task tokens, poll tokens, result meta, page previews) plus graceful degradation when Redis is None
  • All 60 existing tests pass, pre-commit hooks (format, lint, typecheck) pass

🤖 Generated with Claude Code

RafaelPo and others added 2 commits February 21, 2026 12:12
- redis_utils.py: Redis client factory with Sentinel support, exponential
  backoff retry, and key helpers for multi-pod deployments
- state.py: ServerState dataclass with Redis-backed storage for task tokens,
  poll tokens, result metadata, page previews, and CSV results (all with TTLs)
- Add real Redis test infrastructure (redis-server on port 16379) in conftest
- Add redis>=5.0.0 dependency to pyproject.toml
- Add redis-server installation step to CI workflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dantic

- Extract all Redis data operations into RedisStore class, making
  ServerState a thin config/context holder with store: RedisStore | None
- Convert ServerState from dataclass to Pydantic BaseModel with
  ConfigDict(arbitrary_types_allowed=True)
- Add Transport StrEnum (stdio/http) replacing plain str transport field
- Type redis client as Redis instead of Any
- Add logging.warning to store_result_page and get_result_page except
  blocks for consistency with other methods
- Add comment on empty-string build_key test explaining double colons
- Update tests to exercise RedisStore directly and verify ServerState
  defaults including Transport enum

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@RafaelPo RafaelPo merged commit 541e162 into main Feb 21, 2026
5 checks passed
@RafaelPo RafaelPo deleted the feat/redis-infrastructure branch February 21, 2026 12:34
if sentinel_endpoints and sentinel_master_name:
sentinels = []
for ep in sentinel_endpoints.split(","):
h, p = ep.strip().rsplit(":", 1)
Copy link

Choose a reason for hiding this comment

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

Bug: The create_redis_client function is defined but never called in the production code, leaving the Redis integration feature incomplete and non-operational.
Severity: HIGH

Suggested Fix

Integrate the create_redis_client function into the application's initialization logic. This likely involves calling it when the ServerState is created and using its return value to populate the store field if Redis is configured.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: everyrow-mcp/src/everyrow_mcp/redis_utils.py#L42

Potential issue: The function `create_redis_client` in `redis_utils.py` is defined to
establish a connection to a Redis instance, including support for Redis Sentinel.
However, this function is never called anywhere in the production application code. Its
only usage is within the test suite. As a result, even if Redis Sentinel endpoints are
configured, the application will not attempt to connect to Redis, rendering the feature
incomplete and non-functional.

Did we get this right? 👍 / 👎 to inform future reviews.

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.

1 participant