feat: add optional Redis caching layer for API endpoints

Add Redis-backed response caching for read-heavy API endpoints (nodes,
advertisements, messages, channels, dashboard, profiles) with configurable
TTL, key prefix isolation, and graceful fallback when Redis is unavailable.

New files:
- common/redis.py: CacheBackend, NullCache, RedisCacheBackend
- api/cache.py: @cached decorator, sorted_query_string helper
- tests/test_api/test_cache.py: 23 unit tests

Changes:
- pyproject.toml: add redis[hiredis] dependency
- common/config.py: 8 Redis settings on APISettings
- api/cli.py: Redis Click options + startup banner
- api/app.py: Redis lifespan init/cleanup, X-Cache middleware, health check
- 6 route files: apply @cached decorator to list endpoints
- docker-compose.yml: Redis service (cache profile), env vars
- docker-compose.dev.yml: Redis port exposure
- .env.example, README.md, AGENTS.md, docs/upgrading.md: documentation

Redis is disabled by default (REDIS_ENABLED=false). Enable with
--profile cache and REDIS_ENABLED=true.
This commit is contained in:
Louis King
2026-06-09 23:08:49 +01:00
parent a4419a8987
commit 385d1ab141
21 changed files with 1574 additions and 84 deletions
+39
View File
@@ -285,6 +285,45 @@ METRICS_CACHE_TTL=60
# External Prometheus port (when using --profile metrics)
PROMETHEUS_PORT=9090
# -------------------
# Redis Cache
# -------------------
# Optional Redis cache for API response caching.
# Reduces database load for read-heavy endpoints (nodes, messages, dashboard).
# When disabled or unavailable, the API queries the database directly.
#
# Docker: Redis is included in the "cache" profile (--profile cache).
# REDIS_ENABLED defaults to false everywhere. To enable, set REDIS_ENABLED=true
# and start with --profile cache (or point REDIS_HOST at an external Redis).
# Bare-metal: Install Redis separately and set REDIS_ENABLED=true.
#
# For multi-instance setups sharing one Redis, use different REDIS_KEY_PREFIX
# values per instance (e.g., hub for prod, hub-stg for staging).
# Enable Redis caching (default: false outside Docker, true in Docker Compose)
# REDIS_ENABLED=false
# Redis server host (use "redis" in Docker Compose)
# REDIS_HOST=localhost
# Redis server port
# REDIS_PORT=6379
# Redis database number
# REDIS_DB=0
# Redis password (optional)
# REDIS_PASSWORD=
# Cache key prefix for multi-instance isolation
# REDIS_KEY_PREFIX=hub
# Default cache TTL in seconds (matches web auto-refresh interval)
# REDIS_CACHE_TTL=30
# Cache TTL for dashboard endpoints (seconds)
# REDIS_CACHE_TTL_DASHBOARD=30
# External Alertmanager port (when using --profile metrics)
ALERTMANAGER_PORT=9093