-
Notifications
You must be signed in to change notification settings - Fork 300
Change cache buster on every request #3724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
When the client detects a stale cached response from a CDN with an expired shape handle, it retries with a cache buster parameter to bypass the cache. Previously, the cache buster was generated in #onInitialResponse before throwing the error, which could result in the same value being used across retries. Now the cache buster is generated right before each retry request in the StaleCacheError handler, ensuring a unique value for every retry attempt. This guarantees each retry has a different cache buster to bypass different cache layers. Also updated the test to verify that all cache busters are unique across retry attempts. Fixes #3723
📝 WalkthroughWalkthroughThis change ensures the cache-buster value is generated immediately before each CDN retry instead of being reused, by throwing on stale initial responses and generating a fresh timestamp-and-random suffix at retry time (fix for issue Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant RetryHandler
participant CDN
participant Cache
Client->>CDN: Request shape (no or stale buster)
CDN->>Client: Stale handle / stale response
Client->>RetryHandler: throw StaleCacheError
RetryHandler->>RetryHandler: generate new cache-buster (timestamp + random)
RetryHandler->>CDN: Retry request with fresh cache-buster
CDN->>Client: Fresh response
Client->>Cache: update cache with fresh shape
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (2)**/*.{test,spec}.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx,js,jsx,vue}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (2)📚 Learning: 2026-01-14T14:45:05.838ZApplied to files:
📚 Learning: 2026-01-14T14:45:05.838ZApplied to files:
🧬 Code graph analysis (1)packages/typescript-client/test/expired-shapes-cache.test.ts (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
🔇 Additional comments (1)
✏️ Tip: You can disable this entire section by setting Comment |
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3724 +/- ##
==========================================
+ Coverage 84.01% 87.36% +3.35%
==========================================
Files 44 23 -21
Lines 2834 2011 -823
Branches 534 533 -1
==========================================
- Hits 2381 1757 -624
+ Misses 451 252 -199
Partials 2 2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Replace imperative for loop with declarative slice/map pattern and remove redundant searchParams.has() check since get() + toBeNull assertion already validates existence. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Summary
Fixes cache buster generation for CDN stale response retries - each retry now gets a unique cache buster value instead of potentially reusing the same one, ensuring reliable cache bypass across multiple retry attempts.
Reviewer Guidance
Root Cause
The bug occurred because the cache buster was generated in
#onInitialResponsebefore throwingStaleCacheError, but the retry loop in the error handler would call#requestShape()without generating a new value. If multiple retries occurred in quick succession (within the same millisecond, or with same random seed state), they could get identical cache busters - defeating the purpose of the retry mechanism.Approach
Moved cache buster generation from the error detection site (
#onInitialResponse) to the retry site (theStaleCacheErrorcatch block):This ensures a fresh timestamp and random suffix for every retry attempt.
Key Invariants
Non-goals
Trade-offs
Alternative considered: Pass the cache buster as a parameter through the error. Rejected because it would complicate the error interface and the current approach is simpler - generate right before use.
Verification
pnpm --filter @electric-sql/client testThe test
should retry with cache buster when receiving stale cache response with expired handlenow verifies that all cache busters across retry attempts are unique.Files changed
packages/typescript-client/src/client.ts- Moved cache buster generation from#onInitialResponseto theStaleCacheErrorcatch blockpackages/typescript-client/test/expired-shapes-cache.test.ts- Added assertion that all cache busters are unique.changeset/fix-cache-buster-retry.md- Changeset for the patch releaseFixes #3723
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.