Skip to content

Commit 6324a23

Browse files
committed
review fix
1 parent a7be257 commit 6324a23

File tree

7 files changed

+58
-12
lines changed

7 files changed

+58
-12
lines changed

packages/open-next/src/adapters/cache.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
IncrementalCacheContext,
44
IncrementalCacheValue,
55
} from "types/cache";
6-
import { getTagFromValue, hasBeenRevalidated } from "utils/cache";
6+
import { getTagsFromValue, hasBeenRevalidated } from "utils/cache";
77
import { isBinaryContentType } from "../utils/binary";
88
import { debug, error, warn } from "./logger";
99

@@ -116,7 +116,7 @@ export default class Cache {
116116
const cacheData = cachedEntry?.value;
117117

118118
const meta = cacheData?.meta;
119-
const tags = getTagFromValue(cacheData);
119+
const tags = getTagsFromValue(cacheData);
120120
const _lastModified = cachedEntry.lastModified ?? Date.now();
121121
const _hasBeenRevalidated = await hasBeenRevalidated(
122122
key,
@@ -295,6 +295,12 @@ export default class Cache {
295295
break;
296296
}
297297
}
298+
if (
299+
globalThis.openNextConfig.dangerous?.disableTagCache ||
300+
globalThis.tagCache.mode === "nextMode"
301+
) {
302+
return;
303+
}
298304
// Write derivedTags to dynamodb
299305
// If we use an in house version of getDerivedTags in build we should use it here instead of next's one
300306
const derivedTags: string[] =

packages/open-next/src/core/routing/cacheInterceptor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { InternalEvent, InternalResult } from "types/open-next";
55
import type { CacheValue } from "types/overrides";
66
import { emptyReadableStream, toReadableStream } from "utils/stream";
77

8-
import { getTagFromValue, hasBeenRevalidated } from "utils/cache";
8+
import { getTagsFromValue, hasBeenRevalidated } from "utils/cache";
99
import { debug } from "../../adapters/logger";
1010
import { localizePath } from "./i18n";
1111
import { generateMessageGroupId } from "./queue";
@@ -164,7 +164,7 @@ export async function cacheInterceptor(
164164
}
165165
// We need to check the tag cache now
166166
if (cachedData.value?.type === "app") {
167-
const tags = getTagFromValue(cachedData.value);
167+
const tags = getTagsFromValue(cachedData.value);
168168
const _hasBeenRevalidated = await hasBeenRevalidated(
169169
localizedPath,
170170
tags,

packages/open-next/src/overrides/tagCache/constants.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export const MAX_DYNAMO_BATCH_WRITE_ITEM_COUNT = 25;
2-
export const MAX_DYNAMO_BATCH_GET_ITEM_COUNT = 100;
32

43
/**
54
* Sending to dynamo X commands at a time, using about X * 25 write units per batch to not overwhelm DDB

packages/open-next/src/overrides/tagCache/ddb-nextMode.ts renamed to packages/open-next/src/overrides/tagCache/dynamodb-nextMode.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export default {
7575
if (globalThis.openNextConfig.dangerous?.disableTagCache) {
7676
return false;
7777
}
78+
if (tags.length > 100) {
79+
throw new RecoverableError(
80+
"Cannot query more than 100 tags at once. You should not be using this tagCache implementation for this amount of tags",
81+
);
82+
}
7883
const { CACHE_DYNAMO_TABLE } = process.env;
7984
// It's unlikely that we will have more than 100 items to query
8085
// If that's the case, you should not use this tagCache implementation

packages/open-next/src/types/open-next.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ export type IncludedIncrementalCache =
148148
export type IncludedTagCache =
149149
| "dynamodb"
150150
| "dynamodb-lite"
151+
| "dynamodb-nextMode"
151152
| "fs-dev"
152-
| "ddb-nextMode"
153153
| "dummy";
154154

155155
export type IncludedImageLoader = "s3" | "host" | "fs-dev" | "dummy";

packages/open-next/src/types/overrides.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,27 @@ type BaseTagCache = {
100100
name: string;
101101
};
102102

103+
/**
104+
* On get :
105+
We have to check for every tag (after reading the incremental cache) that they have not been revalidated.
106+
107+
In DynamoDB, this would require 1 GetItem per tag (including internal one), more realistically 1 BatchGetItem per get (In terms of pricing, it would be billed as multiple single GetItem)
108+
109+
On set :
110+
We don't have to do anything here
111+
112+
On revalidateTag for each tag :
113+
We have to update a single entry for this tag
114+
115+
Pros :
116+
- No need to prepopulate DDB
117+
- Very little write
118+
119+
Cons :
120+
- Might be slower on read
121+
- One page request (i.e. GET request) could require to check a lot of tags (And some of them multiple time when used with the fetch cache)
122+
- Almost impossible to do automatic cdn revalidation by itself
123+
*/
103124
export type NextModeTagCache = BaseTagCache & {
104125
mode: "nextMode";
105126
hasBeenRevalidated(tags: string[], lastModified?: number): Promise<boolean>;
@@ -109,6 +130,25 @@ export type NextModeTagCache = BaseTagCache & {
109130
getPathsByTags?: (tags: string[]) => Promise<string[]>;
110131
};
111132

133+
/**
134+
* On get :
135+
We just check for the cache key in the tag cache. If it has been revalidated we just return null, otherwise we continue
136+
137+
On set :
138+
We have to write both the incremental cache and check the tag cache for non existing tag/key combination. For non existing tag/key combination, we have to add them
139+
140+
On revalidateTag for each tag :
141+
We have to update every possible combination for the requested tag
142+
143+
Pros :
144+
- Very fast on read
145+
- Only one query per get (On DynamoDB it's a lot cheaper)
146+
- Can allow for automatic cdn invalidation on revalidateTag
147+
148+
Cons :
149+
- Lots of write on set and revalidateTag
150+
- Needs to be prepopulated at build time to work properly
151+
*/
112152
export type OriginalTagCache = BaseTagCache & {
113153
mode?: "original";
114154
getByTag(tag: string): Promise<string[]>;

packages/open-next/src/utils/cache.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ export async function hasBeenRevalidated(
99
return false;
1010
}
1111
if (globalThis.tagCache.mode === "nextMode") {
12-
const hasBeenRevalidated = await globalThis.tagCache.hasBeenRevalidated(
13-
tags,
14-
lastModified,
15-
);
16-
return hasBeenRevalidated;
12+
return await globalThis.tagCache.hasBeenRevalidated(tags, lastModified);
1713
}
1814
// TODO: refactor this, we should introduce a new method in the tagCache interface so that both implementations use hasBeenRevalidated
1915
const _lastModified = await globalThis.tagCache.getLastModified(
@@ -23,7 +19,7 @@ export async function hasBeenRevalidated(
2319
return _lastModified === -1;
2420
}
2521

26-
export function getTagFromValue(value?: CacheValue<false>) {
22+
export function getTagsFromValue(value?: CacheValue<false>) {
2723
if (!value) {
2824
return [];
2925
}

0 commit comments

Comments
 (0)