Skip to content

feat(router): entity caching with L1/L2, shadow mode, and per-request cache controls (3/6)#2955

Draft
SkArchon wants to merge 1 commit into
milinda/entity-caching-1b-demofrom
milinda/entity-caching-2-router
Draft

feat(router): entity caching with L1/L2, shadow mode, and per-request cache controls (3/6)#2955
SkArchon wants to merge 1 commit into
milinda/entity-caching-1b-demofrom
milinda/entity-caching-2-router

Conversation

@SkArchon

Copy link
Copy Markdown
Contributor

Replaces #2945, which was auto-closed as merged when a bad force-push momentarily collapsed the stack branches onto one commit. Same content, same stack position.

Part 2 of 4 — split out from #2777 (jensneuse/entity-caching-v2). Stacked on #2944.

What's included

  • router/pkg/entitycache: in-memory L1, Redis L2, circuit breaker
  • router/core: factoryresolver mapping of proto cache config to planner metadata, graph server wiring, per-request cache-control headers (graphql_handler), plan generator nil guard, config schema + defaults
  • metrics/otel: entity cache metrics (opt-in telemetry) and attributes
  • graphql-go-tools bumped to PR feat: add caching to loader graphql-go-tools#1259 HEAD (resolver/planner side of the feature) — the two must land together
  • router-tests/entity_caching: full integration suite with self-contained gqlgen subgraphs, Redis tests, and a compose tool for testdata/config.json
  • demo: cachegraph/cachegraph_ext/viewer subgraphs, cache-demo runner, latency injector, router cache configs (demo go.mod moves in lockstep with router deps; demo is path-replaced into router-tests builds)

Excluded

router/internal/graphiql/graphiql.html (playground embed) ships in part 3/4 — this PR runs with the previous embedded playground.

Verification

go build ./... passes in router/ and demo/; go vet ./entity_caching/... passes in router-tests/.

🤖 Generated with Claude Code

Update: test subgraphs coupled to demo

The six entity_caching test subgraphs were moved into demo/pkg/subgraphs/cachetest/ and are imported by the suite — same coupling pattern as the main suite (testenvdemo/pkg/subgraphs). router-tests no longer carries subgraph implementations. Pure move: schemas/resolvers/data unchanged, make compose reproduces an identical testdata/config.json, full suite green.

Diff cleanup

  • The no-op-tracer-provider optimization (HasNonDefaultExporter + bootstrap guard) moved to the benchmark/tooling PR (6/6) — it is a general tracing perf change motivated by benchmarking, not entity caching.
  • Reverted ~1.5k lines of demo/pkg/subgraphs/projects/generated proto churn — leftover reserved markers from fields added and removed during development; the GraphQL schema is unchanged.
  • Dropped router/entity-caching.config.yaml (unreferenced sample) and router-tests/entity_caching/graph.yaml (duplicated the subgraph list that cmd/compose owns; nothing consumed it).
  • The gqlgen generate target moved to demo/Makefile (generate-cachetest) next to the subgraphs it regenerates.

Rebased onto main (2026-06-10)

  • graphql-go-tools re-pinned to 63fa1c88 — PR feat: add caching to loader graphql-go-tools#1259 with v2.4.4 merged in (branch entity-caching-v244-merge; conflicts in resolve/context.go + resolve/resolvable.go resolved keeping caching fields + the actualListSizestypeNameStats rename). Needed because main's router uses v2.4.4 APIs (TypeNameStats) that the PR head lacked.
  • All subscription-overhaul adaptation shims dropped in favor of main's versions (websocket, flushwriter, executor, updater, mocks, errors, operation_processor, plan_generator, headers_test).
  • One astjson adaptation the other way: the caching arena rework makes MergeValuesWithPath return 2 values; main's flushwriter call site adapted.
  • cmd/compose replaced with a wgc-based Makefile target (+ restored graph.yaml input) since composition-go was removed on main (chore: remove composition-go #2830); testdata/config.json regenerated with main's composition.
  • entity_caching suite green throughout (incl. the WS subscription populate/invalidate tests, which depend on ExecutionOptions.Caching wiring in the WS path).

… cache controls

Extracted from jensneuse/entity-caching-v2 (PR #2777) — router layer, stacked on
the demo PR. Entity cache OTEL/Prometheus metrics are split into the next PR.

- router/pkg/entitycache: in-memory L1, Redis L2, circuit breaker
- router/core: factoryresolver mapping of proto cache config to planner metadata,
  graph server wiring, per-request cache-control headers (incl. WS subscriptions),
  EntityCacheKeyInterceptor module hook
- graphql-go-tools pinned to 63fa1c88 (PR #1259 + v2.4.4 merged via
  entity-caching-v244-merge branch) — this also moves astjson to the caching
  arena rework (MergeValuesWithPath now returns 2 values; flushwriter adapted)
- router-tests/entity_caching: integration suite consuming demo's cachetest
  subgraphs; config composed via wgc (composition-go was removed on main),
  testdata/config.json regenerated with main's composition
- subscription-overhaul adaptation shims from the old base were dropped in
  favor of main's versions (websocket, flushwriter, executor, updater, mocks)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83ba9a65-d6ee-4ff8-857f-f3193f78f7c5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

❌ Internal Query Planner CI checks failed

The Internal Query Planner CI checks failed in the celestial repository, and this is going to stop the merge of this PR.
If you are part of the WunderGraph organization, you can see the PR with more details.

@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 10.36907% with 510 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.70%. Comparing base (5ef33a6) to head (6f0c915).

Files with missing lines Patch % Lines
router/core/factoryresolver.go 5.50% 98 Missing and 5 partials ⚠️
router/pkg/entitycache/circuit_breaker.go 0.00% 78 Missing ⚠️
router/core/graph_server.go 12.94% 69 Missing and 5 partials ⚠️
router/core/router.go 8.97% 68 Missing and 3 partials ⚠️
router/pkg/entitycache/memory.go 0.00% 65 Missing ⚠️
router/pkg/entitycache/redis.go 0.00% 44 Missing ⚠️
router/core/executor.go 31.70% 28 Missing ⚠️
router/pkg/config/config.go 12.50% 26 Missing and 2 partials ⚠️
router/core/graphql_handler.go 47.05% 13 Missing and 5 partials ⚠️
router/core/supervisor_instance.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                        Coverage Diff                         @@
##           milinda/entity-caching-1b-demo    #2955      +/-   ##
==================================================================
- Coverage                           65.29%   57.70%   -7.60%     
==================================================================
  Files                                 258      245      -13     
  Lines                               27762    27734      -28     
==================================================================
- Hits                                18128    16003    -2125     
- Misses                               8169    10150    +1981     
- Partials                             1465     1581     +116     
Files with missing lines Coverage Δ
router/core/flushwriter.go 78.84% <100.00%> (+5.12%) ⬆️
router/core/modules.go 47.72% <ø> (-20.46%) ⬇️
router/core/router_config.go 93.82% <ø> (ø)
router/core/websocket.go 77.27% <100.00%> (+0.03%) ⬆️
router/core/supervisor_instance.go 0.00% <0.00%> (ø)
router/core/graphql_handler.go 63.42% <47.05%> (+0.70%) ⬆️
router/core/executor.go 74.69% <31.70%> (-11.13%) ⬇️
router/pkg/config/config.go 42.96% <12.50%> (-39.33%) ⬇️
router/pkg/entitycache/redis.go 0.00% <0.00%> (ø)
router/pkg/entitycache/memory.go 0.00% <0.00%> (ø)
... and 4 more

... and 120 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant