Skip to content

feat(cache): add L2CacheKeyInterceptor for custom cache key transformation#1423

Merged
jensneuse merged 1 commit intofeat/add-caching-supportfrom
jensneuse/custom-cache-keys
Mar 4, 2026
Merged

feat(cache): add L2CacheKeyInterceptor for custom cache key transformation#1423
jensneuse merged 1 commit intofeat/add-caching-supportfrom
jensneuse/custom-cache-keys

Conversation

@jensneuse
Copy link
Copy Markdown
Member

@jensneuse jensneuse commented Mar 4, 2026

Summary

Add L2CacheKeyInterceptor function type to CachingOptions, enabling library users (like Cosmo Router) to customize L2 cache keys per-request without modifying graphql-go-tools internals. The interceptor receives SubgraphName and CacheName metadata for conditional customization, and is applied after the existing subgraph header prefix.

Key Changes

  • Added L2CacheKeyInterceptor function type and L2CacheKeyInterceptorInfo struct to v2/pkg/engine/resolve/context.go
  • Applied interceptor in prepareCacheKeys() and buildMutationEntityCacheKey() in v2/pkg/engine/resolve/loader_cache.go
  • Added comprehensive test suite with 4 subtests covering transformation, L1 isolation, metadata passing, and nil behavior

Test Plan

  • All 4 new interceptor tests pass
  • All existing L1/L2 cache tests pass (no regressions)
  • Race detector passes
  • Federation caching tests pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added optional L2 cache key interception feature, enabling custom transformation of cache keys during lookups, writes, and deletions. Interceptor receives contextual metadata including subgraph and cache names. L1 cache behavior remains unaffected.
    • Includes comprehensive test coverage validating interceptor behavior across multiple caching scenarios.

…ation

Add L2CacheKeyInterceptor function type and L2CacheKeyInterceptorInfo struct to
CachingOptions, allowing library users (like Cosmo Router) to customize L2 cache
keys per-request. This enables tenant isolation, custom prefixes/suffixes from
request headers, and flexible cache key transformations without modifying
graphql-go-tools internals.

The interceptor:
- Transforms L2 cache keys after rendering (includes existing subgraph header prefix)
- Receives SubgraphName and CacheName for conditional customization
- Does NOT affect L1 cache keys (per-request, internal optimization)
- Is applied in prepareCacheKeys() and buildMutationEntityCacheKey() for consistency

Includes comprehensive tests covering transformation, L1 isolation, info passing,
and nil (default) behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

The changes introduce a new public API for L2 cache key interception in the resolve layer, allowing optional transformation of L2 cache keys before lookups, writes, and deletions. The interceptor is applied in two code paths (prepareCacheKeys and buildMutationEntityCacheKey) while L1 caching remains unaffected. Comprehensive tests verify behavior across multiple scenarios including transformation, L1 isolation, and nil-case handling.

Changes

Cohort / File(s) Summary
L2 Cache Key Interceptor API
v2/pkg/engine/resolve/context.go
Adds new public types L2CacheKeyInterceptorInfo and L2CacheKeyInterceptor, and extends CachingOptions with a new optional L2CacheKeyInterceptor field for transforming L2 cache keys before lookup/write/delete operations.
L2 Cache Key Interceptor Implementation
v2/pkg/engine/resolve/loader_cache.go
Applies the L2 cache key interceptor (if provided) in two functions: prepareCacheKeys transforms keys in the L2 cache key collection, and buildMutationEntityCacheKey transforms the final mutation entity cache key.
L2 Cache Key Interceptor Tests
v2/pkg/engine/resolve/l2_cache_key_interceptor_test.go
Adds comprehensive test suite with helpers and test cases verifying interceptor transforms L2 keys with tenant prefix, does not affect L1 keys, captures interceptor info payload (SubgraphName and CacheName), and handles nil interceptor case correctly.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cache): add L2CacheKeyInterceptor for custom cache key transformation' directly and specifically describes the main change in the pull request—introducing a new L2 cache key interceptor feature for custom cache key transformation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jensneuse/custom-cache-keys

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
v2/pkg/engine/resolve/loader_cache.go (1)

1094-1101: Please add a mutation-path interceptor test for key symmetry.

This path now transforms mutation entity keys too. A dedicated test through detectMutationEntityImpact would protect delete/get symmetry from regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/resolve/loader_cache.go` around lines 1094 - 1101, Add a
dedicated unit test that uses detectMutationEntityImpact to verify key symmetry
for mutation-path transformations: simulate an
ExecutionOptions.Caching.L2CacheKeyInterceptor (the same interceptor type used
in loader_cache.go) that mutates keys via L2CacheKeyInterceptorInfo
(SubgraphName/CacheName) and assert that mutation-path operations (delete) and
retrieval (get) produce symmetric cache keys; ensure the test registers the
interceptor on l.ctx.ExecutionOptions.Caching.L2CacheKeyInterceptor and fails if
detectMutationEntityImpact reports any asymmetry so future changes to
L2CacheKeyInterceptor application to mutation entity keys are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@v2/pkg/engine/resolve/loader_cache.go`:
- Around line 1094-1101: Add a dedicated unit test that uses
detectMutationEntityImpact to verify key symmetry for mutation-path
transformations: simulate an ExecutionOptions.Caching.L2CacheKeyInterceptor (the
same interceptor type used in loader_cache.go) that mutates keys via
L2CacheKeyInterceptorInfo (SubgraphName/CacheName) and assert that mutation-path
operations (delete) and retrieval (get) produce symmetric cache keys; ensure the
test registers the interceptor on
l.ctx.ExecutionOptions.Caching.L2CacheKeyInterceptor and fails if
detectMutationEntityImpact reports any asymmetry so future changes to
L2CacheKeyInterceptor application to mutation entity keys are caught.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c359189a-0bfc-413d-b6a6-c104f1c4d1ca

📥 Commits

Reviewing files that changed from the base of the PR and between ae8725d and 0378c5c.

📒 Files selected for processing (3)
  • v2/pkg/engine/resolve/context.go
  • v2/pkg/engine/resolve/l2_cache_key_interceptor_test.go
  • v2/pkg/engine/resolve/loader_cache.go

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.

1 participant