Skip to content

Commit 6ff03ec

Browse files
vicbconico974
andauthored
refactor: lastModified moved to ALS (#740)
Co-authored-by: conico974 <nicodorseuil@yahoo.fr>
1 parent 784958f commit 6ff03ec

File tree

8 files changed

+18
-35
lines changed

8 files changed

+18
-35
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@opennextjs/aws": minor
3+
---
4+
5+
refactor: lastModified moved to ALS
6+
7+
BREAKING CHANGE: `lastModified` is moved to ALS as a number from a global map indexed by `requestId`

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ export default class Cache {
194194
return null;
195195
}
196196
const cacheData = cachedEntry?.value;
197-
const requestId = globalThis.__openNextAls.getStore()?.requestId ?? "";
198-
globalThis.lastModified[requestId] = _lastModified;
197+
const store = globalThis.__openNextAls.getStore();
198+
if (store) {
199+
store.lastModified = _lastModified;
200+
}
199201
if (cacheData?.type === "route") {
200202
return {
201203
lastModified: _lastModified,

packages/open-next/src/core/createMainHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ export async function createMainHandler() {
4343
thisFunction.override?.cdnInvalidation,
4444
);
4545

46-
globalThis.lastModified = {};
47-
4846
// From the config, we create the converter
4947
const converter = await resolveConverter(thisFunction.override?.converter);
5048

packages/open-next/src/core/requestHandler.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,6 @@ export async function openNextHandler(
193193
body,
194194
isBase64Encoded,
195195
};
196-
const requestId = store?.requestId;
197-
198-
if (requestId) {
199-
// reset lastModified. We need to do this to avoid memory leaks
200-
delete globalThis.lastModified[requestId];
201-
}
202196

203197
return internalResult;
204198
},

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,9 @@ export async function revalidateIfRequired(
289289
try {
290290
const hash = (str: string) =>
291291
crypto.createHash("md5").update(str).digest("hex");
292-
const requestId = globalThis.__openNextAls.getStore()?.requestId ?? "";
293292

294293
const lastModified =
295-
globalThis.lastModified[requestId] > 0
296-
? globalThis.lastModified[requestId]
297-
: "";
294+
globalThis.__openNextAls.getStore()?.lastModified ?? 0;
298295

299296
// For some weird cases, lastModified is not set, haven't been able to figure out yet why
300297
// For those cases we add the etag to the deduplication id, it might help
@@ -321,15 +318,14 @@ export function fixISRHeaders(headers: OutgoingHttpHeaders) {
321318
"private, no-cache, no-store, max-age=0, must-revalidate";
322319
return;
323320
}
324-
const requestId = globalThis.__openNextAls.getStore()?.requestId ?? "";
325-
const _lastModified = globalThis.lastModified[requestId] ?? 0;
321+
const _lastModified = globalThis.__openNextAls.getStore()?.lastModified ?? 0;
326322
if (headers[CommonHeaders.NEXT_CACHE] === "HIT" && _lastModified > 0) {
327323
// calculate age
328324
const age = Math.round((Date.now() - _lastModified) / 1000);
329325
// extract s-maxage from cache-control
330326
const regex = /s-maxage=(\d+)/;
331327
const cacheControl = headers[CommonHeaders.CACHE_CONTROL];
332-
debug("cache-control", cacheControl, globalThis.lastModified, Date.now());
328+
debug("cache-control", cacheControl, _lastModified, Date.now());
333329
if (typeof cacheControl !== "string") return;
334330
const match = cacheControl.match(regex);
335331
const sMaxAge = match ? Number.parseInt(match[1]) : undefined;

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,13 @@ export interface EdgeRoute {
5555
}
5656

5757
interface OpenNextRequestContext {
58+
// Unique ID for the request.
5859
requestId: string;
5960
pendingPromiseRunner: DetachedPromiseRunner;
6061
isISRRevalidation?: boolean;
6162
mergeHeadersPriority?: "middleware" | "handler";
63+
// Last modified time of the page (used in main functions, only available for ISR/SSG).
64+
lastModified?: number;
6265
waitUntil?: WaitUntil;
6366
}
6467

@@ -99,14 +102,6 @@ declare global {
99102
*/
100103
var disableIncrementalCache: boolean;
101104

102-
/**
103-
* An object that contains the last modified time of the pages.
104-
* Only available in main functions.
105-
* TODO: Integrate this directly in the AsyncLocalStorage context
106-
* Defined in `createMainHandler`.
107-
*/
108-
var lastModified: Record<string, number>;
109-
110105
/**
111106
* A boolean that indicates if Next is V15 or higher.
112107
* Only available in the cache adapter.

packages/tests-unit/tests/adapters/cache.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ describe("CacheHandler", () => {
4949

5050
globalThis.__openNextAls = {
5151
getStore: vi.fn().mockReturnValue({
52-
requestId: "123",
5352
pendingPromiseRunner: {
5453
withResolvers: vi.fn().mockReturnValue({
5554
resolve: vi.fn(),
@@ -69,8 +68,6 @@ describe("CacheHandler", () => {
6968
},
7069
};
7170
globalThis.isNextAfter15 = false;
72-
73-
globalThis.lastModified = {};
7471
});
7572

7673
describe("get", () => {

packages/tests-unit/tests/core/routing/util.test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,6 @@ describe("revalidateIfRequired", () => {
648648
globalThis.__openNextAls = {
649649
getStore: vi.fn(),
650650
};
651-
652-
globalThis.lastModified = {};
653651
});
654652

655653
it("should not send to queue when x-nextjs-cache is not present", async () => {
@@ -692,13 +690,9 @@ describe("fixISRHeaders", () => {
692690
vi.useFakeTimers().setSystemTime("2024-01-02T00:00:00Z");
693691
globalThis.__openNextAls = {
694692
getStore: () => ({
695-
requestId: "123",
693+
lastModified: new Date("2024-01-01T12:00:00Z").getTime(),
696694
}),
697695
};
698-
699-
globalThis.lastModified = {
700-
"123": new Date("2024-01-01T12:00:00Z").getTime(),
701-
};
702696
});
703697

704698
it("should set cache-control directive to must-revalidate when x-nextjs-cache is REVALIDATED", () => {

0 commit comments

Comments
 (0)