Skip to content

runtime/storage: add tenant-scoped Redis runtime provider #108

Description

@XnLemon

Problem

The repository currently has InMemory and PostgreSQL runtime storage, but no Redis-backed provider wired through the Backend Profile and environment bootstrap. This prevents a shared low-latency runtime path for deployments that need Redis for tenant-scoped session state and memory while keeping the provider choice in the versioned execution snapshot.

Desired behavior or contract

Implement the first production-oriented Redis runtime provider under trpcservice/runtime/storage/redis and make it selectable only through an authenticated, tenant-scoped Backend Profile.

The implementation should:

  • provide the RuntimeStore contract for Session/Event, inbound idempotency, event history, Reply Outbox, lease/fencing, retry and reconciliation state;
  • provide the MemoryStore capability in the same provider package, with durable records and explicit asynchronous index handoff semantics;
  • use explicit tenant-scoped key construction and atomic Redis transactions or Lua scripts for event sequence allocation, duplicate claims, CAS updates and lease/fencing transitions;
  • preserve the existing error categories, defensive-copy behavior, context cancellation and close ownership contracts;
  • reject unsafe or unsupported configuration during Catalog validation and bootstrap, and resolve the endpoint/authentication only through the existing secret boundary;
  • expose health/readiness and bounded client-pool timeouts without logging DSNs, passwords, tokens or customer content;
  • include deployment configuration for a local/CI Redis service and an opt-in live conformance/restart test path.

Acceptance criteria

  • A Redis provider can be selected for one tenant through a Backend Profile without changing another tenant's provider or keyspace.
  • The Redis implementation passes the shared RuntimeStore and MemoryStore conformance tests, including duplicate delivery, concurrent CAS, event ordering, lease expiry, fencing rejection, complete reply batch materialization and retry/dead-letter behavior.
  • A two-tenant test proves that equal session, event, memory and reply identifiers cannot cross tenant boundaries, including after reconnect.
  • Redis restart/reconnect behavior is covered for committed Session/Event/Memory/Outbox records; provider unavailability fails closed and does not silently fall back to InMemory.
  • Bootstrap, readiness and shutdown own the Redis client lifecycle correctly; canceled contexts do not leave goroutines or blocked commands behind.
  • Configuration schema, deployment examples and docs/docs/ops.md status are updated, and mkdocs build --strict, formatting, lint, build and targeted tests pass.

Non-goals

  • S3/OSS or other object storage adapters.
  • Qdrant, Milvus, pgvector or another dedicated vector database adapter.
  • Redis-to-PostgreSQL migration/cutover tooling beyond documenting the provider boundary needed by a later issue.
  • OIDC/JWT Admin authentication, expanded Tool policy, new IM protocols or rich-message work.

Integration and compatibility impact

  • Tenant isolation and authorization: every key and operation must carry the trusted tenant_id; prefixes are not a substitute for authorization or conformance tests.
  • Storage schema, retention, or migration: define key names, serialization/schema version, retention policy and cleanup behavior; durable event and outbox facts must not expire silently.
  • Audit, metrics, and tracing: record provider, capability, latency, retry and error class with low-cardinality labels; never record credentials or raw payloads.
  • Backward compatibility: PostgreSQL and InMemory behavior remains unchanged; existing profiles continue to work and unknown Redis configuration fails closed.

Alternatives considered

Keeping Redis as a design-only provider boundary does not give the project a runnable external-backend proof. Implementing every external storage class in one change would make the contract and operational evidence too broad, so this issue intentionally limits the first adapter to Redis.

Activity

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

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions