@rangojs/router 0.0.0-experimental.119 → 0.0.0-experimental.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vite/index.js +1 -1
- package/package.json +1 -1
- package/src/cache/cf/cf-cache-store.ts +56 -3
package/dist/vite/index.js
CHANGED
|
@@ -2130,7 +2130,7 @@ import { resolve } from "node:path";
|
|
|
2130
2130
|
// package.json
|
|
2131
2131
|
var package_default = {
|
|
2132
2132
|
name: "@rangojs/router",
|
|
2133
|
-
version: "0.0.0-experimental.
|
|
2133
|
+
version: "0.0.0-experimental.120",
|
|
2134
2134
|
description: "Django-inspired RSC router with composable URL patterns",
|
|
2135
2135
|
keywords: [
|
|
2136
2136
|
"react",
|
package/package.json
CHANGED
|
@@ -72,6 +72,15 @@ const CACHE_ORIG_CC_HEADER = "x-edge-cache-orig-cc";
|
|
|
72
72
|
*/
|
|
73
73
|
export const MAX_REVALIDATION_INTERVAL = 30;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Maximum time (ms) to wait for an L1 edge cache (CF Cache API) read before
|
|
77
|
+
* giving up and treating it as a miss. The Cache API is normally sub-millisecond
|
|
78
|
+
* per-colo, so a slow `match` signals a degraded colo; we don't want it adding
|
|
79
|
+
* latency to the request. On timeout the lookup is abandoned, a warning is
|
|
80
|
+
* logged, and the read falls through to its normal miss path (L2/KV or render).
|
|
81
|
+
*/
|
|
82
|
+
export const EDGE_LOOKUP_TIMEOUT_MS = 10;
|
|
83
|
+
|
|
75
84
|
// ============================================================================
|
|
76
85
|
// Types
|
|
77
86
|
// ============================================================================
|
|
@@ -341,6 +350,50 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
|
|
|
341
350
|
return caches.default;
|
|
342
351
|
}
|
|
343
352
|
|
|
353
|
+
/**
|
|
354
|
+
* Read from the L1 edge cache with a latency budget. A `match` that takes
|
|
355
|
+
* longer than EDGE_LOOKUP_TIMEOUT_MS is abandoned and reported as a miss
|
|
356
|
+
* (undefined) so a degraded colo cannot stall the request; callers then fall
|
|
357
|
+
* through to their normal miss path (L2/KV or render). The slow `match` is
|
|
358
|
+
* left to settle in the background (errors swallowed) rather than aborted,
|
|
359
|
+
* since the Cache API exposes no cancellation.
|
|
360
|
+
* @internal
|
|
361
|
+
*/
|
|
362
|
+
private async matchWithTimeout(
|
|
363
|
+
cache: Cache,
|
|
364
|
+
request: Request,
|
|
365
|
+
): Promise<Response | undefined> {
|
|
366
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
367
|
+
const timeout = new Promise<{ timedOut: true }>((resolve) => {
|
|
368
|
+
timer = setTimeout(
|
|
369
|
+
() => resolve({ timedOut: true }),
|
|
370
|
+
EDGE_LOOKUP_TIMEOUT_MS,
|
|
371
|
+
);
|
|
372
|
+
});
|
|
373
|
+
try {
|
|
374
|
+
const matchPromise = cache.match(request);
|
|
375
|
+
// The losing branch keeps running; ensure a late rejection can't surface
|
|
376
|
+
// as an unhandled rejection once we've stopped awaiting it.
|
|
377
|
+
matchPromise.catch(() => {});
|
|
378
|
+
const result = await Promise.race([
|
|
379
|
+
matchPromise.then((response) => ({
|
|
380
|
+
timedOut: false as const,
|
|
381
|
+
response,
|
|
382
|
+
})),
|
|
383
|
+
timeout,
|
|
384
|
+
]);
|
|
385
|
+
if (result.timedOut) {
|
|
386
|
+
console.warn(
|
|
387
|
+
`[CFCacheStore] edge cache lookup exceeded ${EDGE_LOOKUP_TIMEOUT_MS}ms; treating as miss`,
|
|
388
|
+
);
|
|
389
|
+
return undefined;
|
|
390
|
+
}
|
|
391
|
+
return result.response;
|
|
392
|
+
} finally {
|
|
393
|
+
if (timer) clearTimeout(timer);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
344
397
|
// ============================================================================
|
|
345
398
|
// Segment Cache Methods
|
|
346
399
|
// ============================================================================
|
|
@@ -360,7 +413,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
|
|
|
360
413
|
try {
|
|
361
414
|
const cache = await this.getCache();
|
|
362
415
|
const request = this.keyToRequest(key);
|
|
363
|
-
const response = await
|
|
416
|
+
const response = await this.matchWithTimeout(cache, request);
|
|
364
417
|
|
|
365
418
|
if (!response) {
|
|
366
419
|
return this.kvGetSegment(key);
|
|
@@ -494,7 +547,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
|
|
|
494
547
|
try {
|
|
495
548
|
const cache = await this.getCache();
|
|
496
549
|
const request = this.keyToRequest(`doc:${key}`);
|
|
497
|
-
const response = await
|
|
550
|
+
const response = await this.matchWithTimeout(cache, request);
|
|
498
551
|
|
|
499
552
|
if (!response || response.status !== 200) {
|
|
500
553
|
return this.kvGetResponse(key);
|
|
@@ -640,7 +693,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
|
|
|
640
693
|
try {
|
|
641
694
|
const cache = await this.getCache();
|
|
642
695
|
const request = this.keyToRequest(`fn:${key}`);
|
|
643
|
-
const response = await
|
|
696
|
+
const response = await this.matchWithTimeout(cache, request);
|
|
644
697
|
|
|
645
698
|
if (!response) return this.kvGetItem(key);
|
|
646
699
|
|