cdk-nextjs 0.7.5 → 0.7.7
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/.jsii +38 -38
- package/.jsii.tabl.json +1 -1
- package/README.md +12 -3
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +31 -13
- package/docs/adapter-runtime.md +1 -1
- package/docs/caching-guide.md +11 -1
- package/docs/harness-coverage.md +11 -9
- package/lib/adapter/adapter.mjs +220 -149
- package/lib/adapter/aws-cache-store.d.ts +242 -7
- package/lib/adapter/aws-cache-store.js +520 -54
- package/lib/adapter/aws-cache-store.test.js +710 -3
- package/lib/adapter/build-outputs.js +23 -1
- package/lib/adapter/build-outputs.test.js +18 -1
- package/lib/adapter/cache-handler.d.ts +4 -3
- package/lib/adapter/cache-handler.js +1 -1
- package/lib/adapter/cache-handler.mjs +552 -91
- package/lib/adapter/cache-handler.test.js +31 -1
- package/lib/adapter/cache-utils.d.ts +68 -2
- package/lib/adapter/cache-utils.js +108 -2
- package/lib/adapter/cache-utils.test.js +45 -1
- package/lib/adapter/init-cache.d.ts +1 -1
- package/lib/adapter/init-cache.js +60 -37
- package/lib/adapter/init-cache.test.js +55 -2
- package/lib/adapter/local-file-cache-handler.d.ts +2 -2
- package/lib/adapter/local-file-cache-handler.js +4 -5
- package/lib/adapter/s3-cache-handler.d.ts +23 -7
- package/lib/adapter/s3-cache-handler.js +63 -27
- package/lib/adapter/s3-cache-handler.test.js +168 -1
- package/lib/adapter/use-cache-common.d.ts +53 -1
- package/lib/adapter/use-cache-common.js +121 -14
- package/lib/adapter/use-cache-common.test.js +138 -1
- package/lib/adapter/use-cache-default-handler.js +36 -6
- package/lib/adapter/use-cache-default-handler.mjs +557 -51
- package/lib/adapter/use-cache-handlers.test.js +247 -7
- package/lib/adapter/use-cache-remote-handler.js +10 -9
- package/lib/adapter/use-cache-remote-handler.mjs +597 -101
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +2 -1
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +35 -13
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +19 -1
- package/lib/nextjs-api.js +1 -1
- package/lib/nextjs-build/nextjs-build.d.ts +0 -7
- package/lib/nextjs-build/nextjs-build.js +4 -11
- package/lib/nextjs-build/nextjs-build.test.js +4 -3
- package/lib/nextjs-cache.js +1 -1
- package/lib/nextjs-compute/nextjs-containers.js +1 -1
- package/lib/nextjs-compute/nextjs-functions.js +1 -1
- package/lib/nextjs-distribution.js +1 -1
- package/lib/nextjs-post-deploy.js +1 -1
- package/lib/nextjs-static-assets.js +1 -1
- package/lib/root-constructs/nextjs-base-construct.js +1 -1
- package/lib/root-constructs/nextjs-global-containers.js +1 -1
- package/lib/root-constructs/nextjs-global-functions.js +1 -1
- package/lib/root-constructs/nextjs-regional-containers.js +1 -1
- package/lib/root-constructs/nextjs-regional-functions.js +1 -1
- package/lib/runtime/core.js +18 -4
- package/lib/runtime/core.test.js +17 -1
- package/lib/runtime/image.d.ts +19 -0
- package/lib/runtime/image.js +28 -2
- package/lib/runtime/image.test.js +43 -1
- package/lib/runtime/lambda.mjs +30 -6
- package/lib/runtime/server.mjs +30 -6
- package/lib/runtime/tag-manifest.d.ts +15 -0
- package/lib/runtime/tag-manifest.js +24 -0
- package/lib/runtime/tag-manifest.test.d.ts +1 -0
- package/lib/runtime/tag-manifest.test.js +21 -0
- package/lib/utils/deployment-build-id.d.ts +11 -0
- package/lib/utils/deployment-build-id.js +15 -0
- package/package.json +3 -3
- package/scripts/e2e-harness/README.md +1 -1
|
@@ -25,6 +25,8 @@ export declare function resolveAwsCacheConfig(): AwsCacheConfig;
|
|
|
25
25
|
* which is what keeps it disjoint from {@link useCacheS3Key}.
|
|
26
26
|
*/
|
|
27
27
|
export declare function buildS3Key(buildId: string, cacheKey: string): string;
|
|
28
|
+
/** `{buildId}/` + {@link cacheObjectName}: the S3 object an entry is stored in. */
|
|
29
|
+
export declare function s3ObjectKey(buildId: string, cacheKey: string): string;
|
|
28
30
|
/**
|
|
29
31
|
* The folder under the build prefix that `'use cache'` entries are stored in.
|
|
30
32
|
* @see useCacheS3Key
|
|
@@ -36,8 +38,9 @@ export declare const USE_CACHE_KEY_PREFIX = "_use-cache";
|
|
|
36
38
|
* Hashed because a `'use cache'` key is the serialized arguments of the call and
|
|
37
39
|
* has no length limit, where an S3 key stops at 1024 bytes. The `.entry` suffix
|
|
38
40
|
* rather than `.json` is what makes a collision with the incremental cache
|
|
39
|
-
* impossible rather than unlikely: every
|
|
40
|
-
* `.json`, including one for a route that happens to be named
|
|
41
|
+
* impossible rather than unlikely: every object {@link s3ObjectKey} names ends
|
|
42
|
+
* in `.json` or `.long`, including one for a route that happens to be named
|
|
43
|
+
* `/_use-cache/…`.
|
|
41
44
|
* Still under the build prefix, so post-deploy pruning drops them with the build.
|
|
42
45
|
*/
|
|
43
46
|
export declare function useCacheS3Key(buildId: string, keyHash: string): string;
|
|
@@ -113,9 +116,36 @@ export declare const BATCH_GET_MAX_KEYS = 100;
|
|
|
113
116
|
* revalidation log, the reads scale with instances instead of requests or tags.
|
|
114
117
|
*/
|
|
115
118
|
export declare const DEFAULT_TAG_REFRESH_MS = 1000;
|
|
119
|
+
/**
|
|
120
|
+
* How far past `refreshIntervalMs` the last refresh may have settled before a
|
|
121
|
+
* `'use cache'` request waits for the next one (see
|
|
122
|
+
* {@link TrackedTagMarkers.behind}). An instance serving steady traffic stays
|
|
123
|
+
* inside it; one that sat idle, or frozen between Lambda invocations, does not.
|
|
124
|
+
*/
|
|
125
|
+
export declare const TAG_REFRESH_GRACE_MS = 1000;
|
|
126
|
+
/** DynamoDB's limit on a sort key, in UTF-8 bytes. */
|
|
127
|
+
export declare const MAX_SORT_KEY_BYTES = 1024;
|
|
128
|
+
/**
|
|
129
|
+
* `#<sha256(tag)>`, standing in for a tag in a sort key it would push past
|
|
130
|
+
* {@link MAX_SORT_KEY_BYTES}. Next.js caps the tags an app names, but not an
|
|
131
|
+
* implicit `_N_T_/…` tag, which is as long as its path, and a rejected write
|
|
132
|
+
* left `revalidatePath` on a long path recorded nowhere.
|
|
133
|
+
*/
|
|
134
|
+
export declare function hashedTag(tag: string): string;
|
|
135
|
+
/**
|
|
136
|
+
* The longest tag a sort key spells out; past it, {@link sortKeyTag} hashes
|
|
137
|
+
* it. One cap for every row the tag is in, so a row's writer and reader agree
|
|
138
|
+
* without each working out what else shares its key. It leaves room for the
|
|
139
|
+
* most any row puts beside the tag: a mapping row's `#<buildId>/#<sha256>`,
|
|
140
|
+
* with the build ID capped at `MAX_BUILD_ID_BYTES`.
|
|
141
|
+
*/
|
|
142
|
+
export declare const MAX_TAG_BYTES = 768;
|
|
143
|
+
/** `tag` as a sort key spells it: itself, or {@link hashedTag} past {@link MAX_TAG_BYTES}. */
|
|
144
|
+
export declare function sortKeyTag(tag: string): string;
|
|
116
145
|
/**
|
|
117
146
|
* The bare-tag marker rows of the revalidation table (`pk = buildId`,
|
|
118
|
-
* `sk = tag
|
|
147
|
+
* `sk = tag`, or {@link hashedTag} past {@link MAX_TAG_BYTES}), which record when a tag
|
|
148
|
+
* was last revalidated and how.
|
|
119
149
|
*
|
|
120
150
|
* The table also holds the incremental cache's `tag#s3Key` mapping rows, which
|
|
121
151
|
* are its own business and stay in `S3CacheHandler`: only the markers mean the
|
|
@@ -166,7 +196,8 @@ export interface RevalidationLogRow {
|
|
|
166
196
|
/**
|
|
167
197
|
* The revalidation log: one row per tag revalidation (`pk = <buildId>#log`,
|
|
168
198
|
* `sk = <Date.now(), zero-padded>#<tag>`), which expires after
|
|
169
|
-
* {@link REVALIDATION_LOG_TTL_MS}.
|
|
199
|
+
* {@link REVALIDATION_LOG_TTL_MS}. A tag past {@link MAX_TAG_BYTES} is
|
|
200
|
+
* {@link hashedTag} there, and spelled out in the row's `longTag` instead.
|
|
170
201
|
*
|
|
171
202
|
* The marker rows stay the source of truth. The log exists so an instance
|
|
172
203
|
* can ask "what was revalidated since I last looked?" in one `Query`, instead
|
|
@@ -278,6 +309,14 @@ export type TrackedTagMarkersOptions = TagTable & {
|
|
|
278
309
|
/** `Math.random`, for when each tag's re-read comes due. */
|
|
279
310
|
random?: () => number;
|
|
280
311
|
debug?: (message: string) => void;
|
|
312
|
+
/**
|
|
313
|
+
* Whether the process can be frozen with a refresh in flight, as a Lambda
|
|
314
|
+
* sandbox is between invocations: then a timer checks it kept running, and
|
|
315
|
+
* one that spanned a freeze does not count. A container is never frozen,
|
|
316
|
+
* so it skips the timer and waits for the refresh in flight, however slow.
|
|
317
|
+
* @default false
|
|
318
|
+
*/
|
|
319
|
+
canFreeze?: boolean;
|
|
281
320
|
};
|
|
282
321
|
/**
|
|
283
322
|
* One instance's copy of the marker rows of the tags it has needed, kept
|
|
@@ -298,15 +337,19 @@ export type TrackedTagMarkersOptions = TagTable & {
|
|
|
298
337
|
* The cost is bounded per instance, not per request:
|
|
299
338
|
* - {@link ensure} reads a tag's marker the first time it is needed and not
|
|
300
339
|
* again until it is evicted, so a tag costs one read per instance, not one
|
|
301
|
-
* per request.
|
|
340
|
+
* per request. An entry created since {@link completeSince} needs no read
|
|
341
|
+
* at all.
|
|
302
342
|
* - {@link refresh}, at most once per `refreshIntervalMs`, sends one `Query`
|
|
303
343
|
* for the log rows written since the last one, and applies those of tags
|
|
304
344
|
* this instance tracks. Concurrent callers share it. Alongside, it re-reads
|
|
305
345
|
* the markers of up to {@link BATCH_GET_MAX_KEYS} tags not read for
|
|
306
346
|
* {@link DEFAULT_TAG_RESYNC_MS}, in one `BatchGetItem`.
|
|
307
347
|
* A revalidation on another instance is therefore seen within
|
|
308
|
-
* `refreshIntervalMs` (plus the query itself)
|
|
309
|
-
*
|
|
348
|
+
* `refreshIntervalMs` (plus the query itself) - by `'use cache'`, from the
|
|
349
|
+
* first request after the query returns, since its `refreshTags` does not wait
|
|
350
|
+
* for it (see `tagMethods`) unless the instance is {@link behind}, which the
|
|
351
|
+
* runtime settles before a page render starts ({@link catchUp}). The instance
|
|
352
|
+
* that ran it applies it itself, at once, with {@link set}.
|
|
310
353
|
*/
|
|
311
354
|
export declare class TrackedTagMarkers {
|
|
312
355
|
private readonly markers;
|
|
@@ -332,10 +375,64 @@ export declare class TrackedTagMarkers {
|
|
|
332
375
|
* result rather than dropped.
|
|
333
376
|
*/
|
|
334
377
|
private readonly pendingRows;
|
|
378
|
+
/**
|
|
379
|
+
* Log rows for tags not tracked and not being read, merged by tag, oldest
|
|
380
|
+
* first: what the log has said about them since {@link completeSince}. Taken
|
|
381
|
+
* into a tag's marker when it is read or written.
|
|
382
|
+
*/
|
|
383
|
+
private readonly logOnly;
|
|
384
|
+
/** See {@link completeSince}. */
|
|
385
|
+
private floor;
|
|
386
|
+
/**
|
|
387
|
+
* The future `expiredAt`s of markers dropped since, as `[from, to]`, in
|
|
388
|
+
* order: once `from` is past, {@link completeSince} moves to `to`, and not
|
|
389
|
+
* before, since only then does it expire anything. `from` and `to` are the
|
|
390
|
+
* same until spans are merged for space ({@link laterFloor}).
|
|
391
|
+
*/
|
|
392
|
+
private readonly laterFloors;
|
|
393
|
+
/** The in-memory entry stores judged by {@link completeSince}. */
|
|
394
|
+
private readonly entryStores;
|
|
395
|
+
/** How many times {@link forget} ran: a read started before one is made again. */
|
|
396
|
+
private forgotten;
|
|
335
397
|
/** Tracked tags whose read failed, for the next refresh to read again. */
|
|
336
398
|
private readonly unread;
|
|
399
|
+
/**
|
|
400
|
+
* Set inside a page render {@link catchUp} let go, for that render alone.
|
|
401
|
+
* See {@link behindInRender}.
|
|
402
|
+
*/
|
|
403
|
+
private readonly caughtUpRender;
|
|
404
|
+
/** When `sync` last scanned the entry stores ({@link oldestEntry}). */
|
|
405
|
+
private lastEntryScan;
|
|
406
|
+
/**
|
|
407
|
+
* No `logOnly` row is known by it or earlier, so a {@link pruneLogged}
|
|
408
|
+
* against it or earlier drops nothing: a marker is only ever known by later,
|
|
409
|
+
* as its `expiredAt` passes.
|
|
410
|
+
*/
|
|
411
|
+
private prunedAgainst;
|
|
412
|
+
/** When the last refresh started, or was skipped. */
|
|
337
413
|
private lastRefresh;
|
|
414
|
+
/**
|
|
415
|
+
* The refresh in flight. One left open across a freeze comes back after the
|
|
416
|
+
* thaw with what it read before, so {@link refresh} waits for it and then
|
|
417
|
+
* for a fresh one, rather than the runtime waiting for it before the freeze:
|
|
418
|
+
* that would bill every Lambda invocation for the query's tail.
|
|
419
|
+
*/
|
|
338
420
|
private refreshing;
|
|
421
|
+
/**
|
|
422
|
+
* When {@link refreshing} last showed the process running: a timer ticks
|
|
423
|
+
* while it is in flight, and a tick that comes late, or none at all, means
|
|
424
|
+
* the process was paused - frozen - since it started.
|
|
425
|
+
*/
|
|
426
|
+
private lastTick;
|
|
427
|
+
/** Whether a tick came late since {@link refreshing} started. */
|
|
428
|
+
private pausedWhileRefreshing;
|
|
429
|
+
private ticker;
|
|
430
|
+
private readonly canFreeze;
|
|
431
|
+
/**
|
|
432
|
+
* When the last refresh settled, either way, unless it spanned a pause: what
|
|
433
|
+
* it knows is from then. See {@link behind}.
|
|
434
|
+
*/
|
|
435
|
+
private settledAt;
|
|
339
436
|
/**
|
|
340
437
|
* Where the next log query starts (`clock()`): the last successful one's
|
|
341
438
|
* start, less {@link REVALIDATION_LOG_LOOKBACK_MS}.
|
|
@@ -350,6 +447,41 @@ export declare class TrackedTagMarkers {
|
|
|
350
447
|
constructor(options: TrackedTagMarkersOptions);
|
|
351
448
|
/** `tag`'s marker as this instance knows it, if it tracks `tag`. */
|
|
352
449
|
get(tag: string): TagMarker | undefined;
|
|
450
|
+
/**
|
|
451
|
+
* Since when (`markerClock()`) this instance knows of every revalidation of
|
|
452
|
+
* every tag, tracked or not: tracked ones from their markers and the log,
|
|
453
|
+
* the others from the log alone (`logOnly`). So an entry created at or after
|
|
454
|
+
* it can be judged by {@link state} and {@link expiration} without
|
|
455
|
+
* {@link ensure} reading anything - which matters inside a `'use cache'`
|
|
456
|
+
* lookup, where Next.js waits for the answer and a read pushes the entry out
|
|
457
|
+
* of the static stage of a staged render.
|
|
458
|
+
*
|
|
459
|
+
* Starts at construction: the log is followed from before it. Moves to now
|
|
460
|
+
* when the tracked markers are forgotten, and past the revalidations of
|
|
461
|
+
* whatever else it lets go of - a marker evicted for space, a log row
|
|
462
|
+
* pruned - which are no longer known: to its `expiredAt` only once that is
|
|
463
|
+
* past, since a profile's `expire` can be a year out, and moving there at
|
|
464
|
+
* once would turn the read-free path off for the instance's life.
|
|
465
|
+
*
|
|
466
|
+
* A row is pruned only once it is no later than every entry held, so that
|
|
467
|
+
* costs those entries nothing. An entry stored afterwards with an older
|
|
468
|
+
* `timestamp` - Next.js stamps the start of its generation, which can
|
|
469
|
+
* outlast a lookback - is older than this too, and is read first.
|
|
470
|
+
*
|
|
471
|
+
* It does not cover a revalidation older than the log's first lookback
|
|
472
|
+
* whose `expiredAt` is still to come, which would expire an entry created
|
|
473
|
+
* after it. So the `'use cache'` handler reads an entry's tags in the
|
|
474
|
+
* background as it stores it.
|
|
475
|
+
*/
|
|
476
|
+
get completeSince(): number;
|
|
477
|
+
/**
|
|
478
|
+
* Register an in-memory store whose entries are judged by
|
|
479
|
+
* {@link completeSince}, by the `timestamp` of the oldest entry it holds:
|
|
480
|
+
* `logOnly` keeps the rows that could still apply to one of them, and no
|
|
481
|
+
* others. With none registered it keeps nothing. Asked with `scan` false,
|
|
482
|
+
* `oldestTimestamp` may answer early, but never late, without a scan.
|
|
483
|
+
*/
|
|
484
|
+
judgeEntriesOf(oldestTimestamp: (scan: boolean) => number, holdsAny?: () => boolean): void;
|
|
353
485
|
/**
|
|
354
486
|
* Track `tag` with `marker`: what this instance just wrote, which it knows
|
|
355
487
|
* without reading it back.
|
|
@@ -381,11 +513,73 @@ export declare class TrackedTagMarkers {
|
|
|
381
513
|
* tags may have been revalidated at any time before.
|
|
382
514
|
*/
|
|
383
515
|
ensure(tags: readonly string[]): Promise<void>;
|
|
516
|
+
/**
|
|
517
|
+
* {@link readInto} `tags`, as the read of each that whoever needs one of
|
|
518
|
+
* them next waits on ({@link reading}). Never rejects: a failed read leaves
|
|
519
|
+
* the tags tracked.
|
|
520
|
+
*/
|
|
521
|
+
private startRead;
|
|
522
|
+
/**
|
|
523
|
+
* Whether the last refresh settled more than `refreshIntervalMs` plus
|
|
524
|
+
* {@link TAG_REFRESH_GRACE_MS} ago - one that spanned a freeze counts from
|
|
525
|
+
* when it started: after the instance sat idle or frozen - or always, with
|
|
526
|
+
* a `refreshIntervalMs` of `0`. Answering from what it knows then could
|
|
527
|
+
* serve an entry revalidated elsewhere since, however long ago that was, so
|
|
528
|
+
* `refreshTags` waits for the refresh, and the runtime waits for it before
|
|
529
|
+
* a page render starts ({@link catchUp}).
|
|
530
|
+
*
|
|
531
|
+
* From when it settled, not when it started, so a slow query the runtime
|
|
532
|
+
* waited for before the render does not leave the instance behind inside
|
|
533
|
+
* it. A failed one counts too, so one request does not wait for two: the
|
|
534
|
+
* same "assume the entry is valid" a failed read answers with, until the
|
|
535
|
+
* next refresh, at most the interval and the grace later.
|
|
536
|
+
*/
|
|
537
|
+
get behind(): boolean;
|
|
538
|
+
/**
|
|
539
|
+
* {@link behind}, as `refreshTags` asks it: never inside a page's render
|
|
540
|
+
* {@link catchUp} caught up, since the runtime settled it for that request
|
|
541
|
+
* before the render started, and a wait inside a `'use cache'` lookup is
|
|
542
|
+
* what it settled it to avoid - a render crossing the line partway through
|
|
543
|
+
* would otherwise wait after all. So a revalidation elsewhere can go unseen
|
|
544
|
+
* for a render's duration on top of the usual window.
|
|
545
|
+
*
|
|
546
|
+
* A route handler, which no catch-up precedes, waits at the plain line.
|
|
547
|
+
*/
|
|
548
|
+
get behindInRender(): boolean;
|
|
549
|
+
/**
|
|
550
|
+
* Whether a registered store ({@link judgeEntriesOf}) holds any entry: one
|
|
551
|
+
* a refresh could expire. With none there is nothing to wait for even when
|
|
552
|
+
* the instance is {@link behind}, since whatever is stored from here on is
|
|
553
|
+
* newer than what the log would say - which covers the first `'use cache'`
|
|
554
|
+
* call of a process, which creates the handler inside the render.
|
|
555
|
+
*/
|
|
556
|
+
get holdsEntries(): boolean;
|
|
557
|
+
/**
|
|
558
|
+
* {@link refresh}, waited for when the instance is {@link behind}. The
|
|
559
|
+
* runtime calls it before handing a page request to Next.js, outside the
|
|
560
|
+
* staged render whose static stage a wait inside a `'use cache'` lookup
|
|
561
|
+
* would cut short. Only for the `'use cache'` handler's entries
|
|
562
|
+
* ({@link judgeEntriesOf}): the other caches wait for the refresh where they
|
|
563
|
+
* read anyway. Not with a `refreshIntervalMs` of `0` either, where
|
|
564
|
+
* `refreshTags` asks again regardless. Then `render`, marked as caught up
|
|
565
|
+
* for ({@link behindInRender}). Rejects only as `render` does.
|
|
566
|
+
*/
|
|
567
|
+
catchUp<T>(render: () => Promise<T>): Promise<T>;
|
|
568
|
+
/** Whether `at` is more than the interval and the grace ago. */
|
|
569
|
+
private overdue;
|
|
384
570
|
/**
|
|
385
571
|
* Catch up on revalidations other instances ran, at most once per
|
|
386
572
|
* `refreshIntervalMs`. See {@link TrackedTagMarkers} for the cost.
|
|
387
573
|
*/
|
|
388
574
|
refresh(): Promise<void>;
|
|
575
|
+
private startTicking;
|
|
576
|
+
private stopTicking;
|
|
577
|
+
/**
|
|
578
|
+
* Whether the process was paused since {@link refreshing} started: a tick
|
|
579
|
+
* came late, or the next one is overdue (after a thaw, a request can run
|
|
580
|
+
* before the timer does).
|
|
581
|
+
*/
|
|
582
|
+
private pausedSinceRefreshStarted;
|
|
389
583
|
/**
|
|
390
584
|
* Record a revalidation of `tags`: here at once, and in the revalidation
|
|
391
585
|
* table for every other instance - the marker row plus a log row per tag.
|
|
@@ -458,6 +652,47 @@ export declare class TrackedTagMarkers {
|
|
|
458
652
|
*/
|
|
459
653
|
private readInto;
|
|
460
654
|
private takePendingRows;
|
|
655
|
+
/**
|
|
656
|
+
* What this instance knows of `tag`: tracked, or from the log alone -
|
|
657
|
+
* including rows that arrived while its first read is in flight.
|
|
658
|
+
*/
|
|
659
|
+
private knownMarker;
|
|
660
|
+
/**
|
|
661
|
+
* Keep `tag`'s log rows in `logOnly`, unless they cannot apply to an entry
|
|
662
|
+
* held, `oldest` or newer (see {@link pruneLogged}), as bounded as the
|
|
663
|
+
* tracked tags. Either way a row let go of takes what it knew with it, so
|
|
664
|
+
* `completeSince` moves past it.
|
|
665
|
+
*/
|
|
666
|
+
private rememberLogged;
|
|
667
|
+
/**
|
|
668
|
+
* Drop the `logOnly` rows that cannot apply to an entry held, `oldest` or
|
|
669
|
+
* newer: every revalidation they name so far is no later than it. That
|
|
670
|
+
* moves `completeSince` no further than `oldest`, which costs the entries
|
|
671
|
+
* held nothing, and a profile's `expiredAt` still to come waits in
|
|
672
|
+
* `laterFloors`. Without this, a deployment revalidating many distinct tags
|
|
673
|
+
* filled `logOnly` with tags no entry here carries, and the evictions past
|
|
674
|
+
* its bound kept moving `completeSince` up to the present.
|
|
675
|
+
*/
|
|
676
|
+
private pruneLogged;
|
|
677
|
+
/**
|
|
678
|
+
* The oldest entry timestamp of any registered store, `Infinity` with none:
|
|
679
|
+
* early, never late, unless `scan`.
|
|
680
|
+
*/
|
|
681
|
+
private oldestEntry;
|
|
682
|
+
/**
|
|
683
|
+
* Move `completeSince` past `marker`'s revalidations: what is no longer
|
|
684
|
+
* known about a tag once its marker is dropped. A future `expiredAt` waits
|
|
685
|
+
* in `laterFloors` until it is past.
|
|
686
|
+
*/
|
|
687
|
+
private raiseFloor;
|
|
688
|
+
/**
|
|
689
|
+
* Add `time` to `laterFloors`, in order. Past the tracked-tag bound the two
|
|
690
|
+
* spans closest together are merged: from the first's start,
|
|
691
|
+
* `completeSince` is the second's end, early - which only costs reads, and
|
|
692
|
+
* for as short a time as any merge allows. Never later than its time, which
|
|
693
|
+
* would let an entry expire unseen.
|
|
694
|
+
*/
|
|
695
|
+
private laterFloor;
|
|
461
696
|
/** Record that `tag`'s marker was known from the table at `at`. */
|
|
462
697
|
private known;
|
|
463
698
|
private remember;
|