Skip to content

Commit cabd61e

Browse files
committed
review fix
1 parent 61ecbb5 commit cabd61e

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

@@ -115,7 +115,7 @@ export default class Cache {
115115

116116
const cacheData = cachedEntry?.value;
117117
const meta = cacheData?.meta;
118-
const tags = getTagFromValue(cacheData);
118+
const tags = getTagsFromValue(cacheData);
119119
const _lastModified = cachedEntry.lastModified ?? Date.now();
120120
const _hasBeenRevalidated = await hasBeenRevalidated(
121121
key,
@@ -291,6 +291,12 @@ export default class Cache {
291291
break;
292292
}
293293
}
294+
if (
295+
globalThis.openNextConfig.dangerous?.disableTagCache ||
296+
globalThis.tagCache.mode === "nextMode"
297+
) {
298+
return;
299+
}
294300
// Write derivedTags to dynamodb
295301
// If we use an in house version of getDerivedTags in build we should use it here instead of next's one
296302
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 "./util";
@@ -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
@@ -147,8 +147,8 @@ export type IncludedIncrementalCache =
147147
export type IncludedTagCache =
148148
| "dynamodb"
149149
| "dynamodb-lite"
150+
| "dynamodb-nextMode"
150151
| "fs-dev"
151-
| "ddb-nextMode"
152152
| "dummy";
153153

154154
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
@@ -90,6 +90,27 @@ type BaseTagCache = {
9090
name: string;
9191
};
9292

93+
/**
94+
* On get :
95+
We have to check for every tag (after reading the incremental cache) that they have not been revalidated.
96+
97+
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)
98+
99+
On set :
100+
We don't have to do anything here
101+
102+
On revalidateTag for each tag :
103+
We have to update a single entry for this tag
104+
105+
Pros :
106+
- No need to prepopulate DDB
107+
- Very little write
108+
109+
Cons :
110+
- Might be slower on read
111+
- 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)
112+
- Almost impossible to do automatic cdn revalidation by itself
113+
*/
93114
export type NextModeTagCache = BaseTagCache & {
94115
mode: "nextMode";
95116
hasBeenRevalidated(tags: string[], lastModified?: number): Promise<boolean>;
@@ -99,6 +120,25 @@ export type NextModeTagCache = BaseTagCache & {
99120
getPathsByTags?: (tags: string[]) => Promise<string[]>;
100121
};
101122

123+
/**
124+
* On get :
125+
We just check for the cache key in the tag cache. If it has been revalidated we just return null, otherwise we continue
126+
127+
On set :
128+
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
129+
130+
On revalidateTag for each tag :
131+
We have to update every possible combination for the requested tag
132+
133+
Pros :
134+
- Very fast on read
135+
- Only one query per get (On DynamoDB it's a lot cheaper)
136+
- Can allow for automatic cdn invalidation on revalidateTag
137+
138+
Cons :
139+
- Lots of write on set and revalidateTag
140+
- Needs to be prepopulated at build time to work properly
141+
*/
102142
export type OriginalTagCache = BaseTagCache & {
103143
mode?: "original";
104144
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)