Skip to content

feat: expose cache namespace across keys and metrics#64

Merged
lan17 merged 3 commits into
mainfrom
agent/cache-namespace
Jul 18, 2026
Merged

feat: expose cache namespace across keys and metrics#64
lan17 merged 3 commits into
mainfrom
agent/cache-namespace

Conversation

@lan17

@lan17 lan17 commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Context

DialCache exposes its logical cache-key prefix as urnPrefix and separately allows redis.keyPrefix to 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

  • Rename DialCacheConfig.urnPrefix, DialCacheKeyInit.urnPrefix, and DialCacheKey.urnPrefix to namespace.
  • Keep the default value "urn".
  • Use namespace as the sole cache identity and key-partitioning option across every cache layer, coalescing, deterministic ramp, invalidation, and metrics.
  • Remove redis.keyPrefix from RedisConfig and runtime key construction.
  • Reject any own legacy redis.keyPrefix property, including undefined, so untyped and JavaScript callers cannot silently move to an unprefixed Redis keyspace.
  • Reject any own legacy urnPrefix property in both DialCache and direct DialCacheKey construction.
  • Reject namespaces containing { or } immediately at both construction surfaces, even for local-only and untracked caches.
  • Add backend-neutral cacheNamespace to every metrics path and map it to Prometheus/Datadog cache_namespace without changing metric names.
  • Keep DatadogMetricsOptions.namespace as 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 plain feat: classification.

TypeScript callers must rename urnPrefix to namespace and remove redis.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:

// Before
new DialCache({
  urnPrefix: "users-api",
  redis: { client: redisClient, keyPrefix: "production:" },
});

// After
new DialCache({
  namespace: "production-users-api",
  redis: { client: redisClient },
});

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 when DialCache or DialCacheKey is 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.namespace remains independent: it controls the Datadog metric-name prefix, not cache identity.

Validation

  • git diff --check
  • Node 22.22.0 pnpm check: strict types, 12 files / 172 tests, ESM/CJS/declarations, packed consumers
  • pnpm test:integration: 3 files / 46 Redis 6.2, Valkey 8, and Redis Cluster tests
  • Fresh review loop: API/runtime review found one migration-documentation gap; fixed and independently re-reviewed with no findings
  • Exact-head GitHub Actions CI passed

Closes #15

@lan17
lan17 force-pushed the agent/cache-namespace branch from b9ee9ee to f6f04ac Compare July 18, 2026 03:47
@lan17
lan17 marked this pull request as ready for review July 18, 2026 04:27
@lan17
lan17 merged commit 8dfef8d into main Jul 18, 2026
5 checks passed
@lan17
lan17 deleted the agent/cache-namespace branch July 18, 2026 05:56
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.

Rename urnPrefix to namespace and expose cache namespace metrics

1 participant