feat(api): Redis read cache for product details and search
Stage-0 caching from docs/scalability.md. The Go API now caches hot product-detail and search-result reads in Redis with a fail-open, epoch-versioned scheme; Python ingestion bumps the epoch after a write run to invalidate the cache globally in O(1). - api/internal/cache: fail-open Cache (GetJSON/SetJSON) namespaced by an epoch counter (og:cache:epoch); disabled when Redis is unconfigured. - store: ProductByID/ProductByGTIN (24h TTL) and SearchProducts (1h TTL) read-through the cache via WithCache. - ingestion: bump_cache_epoch() called after update_off/seed_off/ import_bypos/dedup commits when rows changed; best-effort, never fails a run. Adds redis dependency. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"""Tests for the best-effort API cache invalidation signal."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
import opengoods.cache as cache
|
||||
|
||||
|
||||
def test_disabled_when_no_url(monkeypatch):
|
||||
monkeypatch.delenv("OPENGOODS_REDIS_URL", raising=False)
|
||||
assert cache.default_redis_url() is None
|
||||
assert cache.bump_cache_epoch() is False
|
||||
|
||||
|
||||
def test_bump_fails_open_when_unreachable(monkeypatch):
|
||||
# An unroutable URL must not raise; the run still succeeds.
|
||||
monkeypatch.setenv("OPENGOODS_REDIS_URL", "redis://127.0.0.1:1/0")
|
||||
assert cache.bump_cache_epoch() is False
|
||||
|
||||
|
||||
def test_bump_increments_epoch(monkeypatch):
|
||||
calls = {}
|
||||
|
||||
class FakeClient:
|
||||
def incr(self, key):
|
||||
calls["key"] = key
|
||||
return 7
|
||||
|
||||
def close(self):
|
||||
calls["closed"] = True
|
||||
|
||||
class FakeRedis:
|
||||
@staticmethod
|
||||
def from_url(url, **kwargs):
|
||||
calls["url"] = url
|
||||
return FakeClient()
|
||||
|
||||
monkeypatch.setitem(sys.modules, "redis", type("M", (), {"Redis": FakeRedis}))
|
||||
|
||||
assert cache.bump_cache_epoch("redis://example:6379/0") is True
|
||||
assert calls["key"] == "og:cache:epoch"
|
||||
assert calls["url"] == "redis://example:6379/0"
|
||||
assert calls["closed"] is True
|
||||
Reference in New Issue
Block a user