feat: expose cache namespace across keys and metrics#64
Merged
Conversation
lan17
force-pushed
the
agent/cache-namespace
branch
from
July 18, 2026 03:47
b9ee9ee to
f6f04ac
Compare
lan17
marked this pull request as ready for review
July 18, 2026 04:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
DialCache exposes its logical cache-key prefix as
urnPrefixand separately allowsredis.keyPrefixto alter only Redis storage. Those overlapping knobs make cache identity harder to reason about: two instances can report the same logical namespace while using different Redis values and invalidation watermarks.This change establishes one cache-domain concept—
namespace—across keys, invalidation, ramp cohorts, coalescing, and telemetry. It also makes namespace validation independent of whether Redis or invalidation tracking is active.Design
DialCacheConfig.urnPrefix,DialCacheKeyInit.urnPrefix, andDialCacheKey.urnPrefixtonamespace."urn".namespaceas the sole cache identity and key-partitioning option across every cache layer, coalescing, deterministic ramp, invalidation, and metrics.redis.keyPrefixfromRedisConfigand runtime key construction.redis.keyPrefixproperty, includingundefined, so untyped and JavaScript callers cannot silently move to an unprefixed Redis keyspace.urnPrefixproperty in bothDialCacheand directDialCacheKeyconstruction.{or}immediately at both construction surfaces, even for local-only and untracked caches.cacheNamespaceto every metrics path and map it to Prometheus/Datadogcache_namespacewithout changing metric names.DatadogMetricsOptions.namespaceas the separate metric-name prefix.Compatibility and migration
This changes public configuration, Redis key layout for callers that used
redis.keyPrefix, and the metrics schema. The PR intentionally retains its plainfeat:classification.TypeScript callers must rename
urnPrefixtonamespaceand removeredis.keyPrefix. JavaScript and untyped callers receive focused migration errors for either removed property.For callers that did not configure
redis.keyPrefix, keeping the same value while renaming the property preserves exact key and watermark bytes, deterministic ramp cohorts, and cache behavior.A non-empty legacy Redis prefix cannot be preserved independently. Choose one namespace that represents the complete cache domain:
This creates a new Redis keyspace, and changing the namespace also creates a boundary across in-memory layers, coalescing, ramp cohorts, invalidation, and metrics. Old and new versions do not share Redis values or invalidation watermarks. During an overlapping deployment, an invalidation handled by one version is invisible to the other, which can continue serving a stale tracked value until its value TTL expires. If remote invalidation correctness matters, a normal rolling deployment is unsafe: use a coordinated no-overlap cutover, or an operational bridge that prevents both versions from serving remote cache across mutations (for example, temporarily disable and clear remote caching during the transition). After cutover, provision for fallback/refill load and allow old Redis state to expire by TTL.
Namespaces containing
{or}are rejected whenDialCacheorDialCacheKeyis constructed rather than later when a tracked Redis key is exercised.Prometheus collectors gain required
cache_namespace, and Datadog metrics gain the corresponding tag. Exact-label dashboards and alerts need updating. Old-schema Prometheus collectors cannot share the same registry/name with upgraded collectors.DatadogMetricsOptions.namespaceremains independent: it controls the Datadog metric-name prefix, not cache identity.Validation
git diff --checkpnpm check: strict types, 12 files / 172 tests, ESM/CJS/declarations, packed consumerspnpm test:integration: 3 files / 46 Redis 6.2, Valkey 8, and Redis Cluster testsCloses #15