Skip to content

Commit e897334

Browse files
committed
refactor: store WaitUntil in ALS
1 parent 867defe commit e897334

File tree

15 files changed

+73
-45
lines changed

15 files changed

+73
-45
lines changed

packages/open-next/src/adapters/edge-adapter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { ReadableStream } from "node:stream/web";
22

3-
import type { InternalEvent, InternalResult } from "types/open-next";
3+
import type { InternalEvent, InternalResult, WaitUntil } from "types/open-next";
44
import { runWithOpenNextRequestContext } from "utils/promise";
55
import { emptyReadableStream } from "utils/stream";
66

@@ -16,12 +16,13 @@ globalThis.__openNextAls = new AsyncLocalStorage();
1616

1717
const defaultHandler = async (
1818
internalEvent: InternalEvent,
19+
options?: { waitUntil?: WaitUntil },
1920
): Promise<InternalResult> => {
2021
globalThis.isEdgeRuntime = true;
2122

2223
// We run everything in the async local storage context so that it is available in edge runtime functions
2324
return runWithOpenNextRequestContext(
24-
{ isISRRevalidation: false },
25+
{ isISRRevalidation: false, waitUntil: options?.waitUntil },
2526
async () => {
2627
const host = internalEvent.headers.host
2728
? `https://${internalEvent.headers.host}`

packages/open-next/src/adapters/image-optimization-adapter.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import type {
2222
InternalEvent,
2323
InternalResult,
2424
StreamCreator,
25+
WaitUntil,
2526
} from "types/open-next.js";
2627
import { emptyReadableStream, toReadableStream } from "utils/stream.js";
2728

@@ -58,7 +59,7 @@ export const handler = await createGenericHandler({
5859

5960
export async function defaultHandler(
6061
event: InternalEvent,
61-
streamCreator?: StreamCreator,
62+
options?: { streamCreator?: StreamCreator; waitUntil?: WaitUntil },
6263
): Promise<InternalResult> {
6364
// Images are handled via header and query param information.
6465
debug("handler event", event);
@@ -99,9 +100,9 @@ export async function defaultHandler(
99100
downloadHandler,
100101
);
101102

102-
return buildSuccessResponse(result, streamCreator, etag);
103+
return buildSuccessResponse(result, options?.streamCreator, etag);
103104
} catch (e: any) {
104-
return buildFailureResponse(e, streamCreator);
105+
return buildFailureResponse(e, options?.streamCreator);
105106
}
106107
}
107108

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type {
22
InternalEvent,
33
InternalResult,
44
MiddlewareResult,
5+
WaitUntil,
56
} from "types/open-next";
67
import { runWithOpenNextRequestContext } from "utils/promise";
78

@@ -24,6 +25,7 @@ globalThis.__openNextAls = new AsyncLocalStorage();
2425

2526
const defaultHandler = async (
2627
internalEvent: InternalEvent,
28+
options?: { waitUntil?: WaitUntil },
2729
): Promise<InternalResult | MiddlewareResult> => {
2830
const originResolver = await resolveOriginResolver(
2931
globalThis.openNextConfig.middleware?.originResolver,
@@ -49,7 +51,10 @@ const defaultHandler = async (
4951

5052
// We run everything in the async local storage context so that it is available in the external middleware
5153
return runWithOpenNextRequestContext(
52-
{ isISRRevalidation: internalEvent.headers["x-isr"] === "1" },
54+
{
55+
isISRRevalidation: internalEvent.headers["x-isr"] === "1",
56+
waitUntil: options?.waitUntil,
57+
},
5358
async () => {
5459
const result = await routingHandler(internalEvent);
5560
if ("internalEvent" in result) {

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
ResolvedRoute,
99
RoutingResult,
1010
StreamCreator,
11+
WaitUntil,
1112
} from "types/open-next";
1213
import { runWithOpenNextRequestContext } from "utils/promise";
1314

@@ -29,12 +30,18 @@ patchAsyncStorage();
2930

3031
export async function openNextHandler(
3132
internalEvent: InternalEvent,
32-
responseStreaming?: StreamCreator,
33+
options?: {
34+
streamCreator?: StreamCreator;
35+
waitUntil?: WaitUntil;
36+
},
3337
): Promise<InternalResult> {
3438
const initialHeaders = internalEvent.headers;
3539
// We run everything in the async local storage context so that it is available in the middleware as well as in NextServer
3640
return runWithOpenNextRequestContext(
37-
{ isISRRevalidation: initialHeaders["x-isr"] === "1" },
41+
{
42+
isISRRevalidation: initialHeaders["x-isr"] === "1",
43+
waitUntil: options?.waitUntil,
44+
},
3845
async () => {
3946
if (initialHeaders["x-forwarded-host"]) {
4047
initialHeaders.host = initialHeaders["x-forwarded-host"];
@@ -116,7 +123,7 @@ export async function openNextHandler(
116123

117124
if ("type" in routingResult) {
118125
// response is used only in the streaming case
119-
if (responseStreaming) {
126+
if (options?.streamCreator) {
120127
const response = createServerResponse(
121128
{
122129
internalEvent,
@@ -127,7 +134,7 @@ export async function openNextHandler(
127134
initialPath: internalEvent.rawPath,
128135
},
129136
headers,
130-
responseStreaming,
137+
options.streamCreator,
131138
);
132139
response.statusCode = routingResult.statusCode;
133140
response.flushHeaders();
@@ -171,7 +178,7 @@ export async function openNextHandler(
171178
const res = createServerResponse(
172179
routingResult,
173180
overwrittenResponseHeaders,
174-
responseStreaming,
181+
options?.streamCreator,
175182
);
176183

177184
await processRequest(req, res, preprocessedEvent);

packages/open-next/src/overrides/wrappers/aws-lambda-streaming.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ const handler: WrapperHandler = async (handler, converter) =>
9494
},
9595
};
9696

97-
const response = await handler(internalEvent, streamCreator);
97+
const response = await handler(internalEvent, { streamCreator });
9898

9999
const isUsingEdge = globalThis.isEdgeRuntime ?? false;
100100
if (isUsingEdge) {

packages/open-next/src/overrides/wrappers/aws-lambda.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ const handler: WrapperHandler =
6161
},
6262
};
6363

64-
const response = await handler(internalEvent, fakeStream);
64+
const response = await handler(internalEvent, {
65+
streamCreator: fakeStream,
66+
});
6567

6668
return converter.convertTo(response, event);
6769
};

packages/open-next/src/overrides/wrappers/cloudflare-edge.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ const handler: WrapperHandler<
3333
ctx: WorkerContext,
3434
): Promise<Response> => {
3535
globalThis.process = process;
36-
globalThis.openNextWaitUntil = ctx.waitUntil.bind(ctx);
3736

3837
// Set the environment variables
3938
// Cloudflare suggests to not override the process.env object but instead apply the values to it
@@ -63,7 +62,9 @@ const handler: WrapperHandler<
6362
}
6463
}
6564

66-
const response = await handler(internalEvent);
65+
const response = await handler(internalEvent, {
66+
waitUntil: ctx.waitUntil.bind(ctx),
67+
});
6768

6869
const result: Response = await converter.convertTo(response);
6970

packages/open-next/src/overrides/wrappers/cloudflare-node.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const handler: WrapperHandler<InternalEvent, InternalResult> =
1818
ctx: any,
1919
): Promise<Response> => {
2020
globalThis.process = process;
21-
globalThis.openNextWaitUntil = ctx.waitUntil.bind(ctx);
2221

2322
// Set the environment variables
2423
// Cloudflare suggests to not override the process.env object but instead apply the values to it
@@ -75,7 +74,12 @@ const handler: WrapperHandler<InternalEvent, InternalResult> =
7574
},
7675
};
7776

78-
ctx.waitUntil(handler(internalEvent, streamCreator));
77+
ctx.waitUntil(
78+
handler(internalEvent, {
79+
streamCreator,
80+
waitUntil: ctx.waitUntil.bind(ctx),
81+
}),
82+
);
7983

8084
return promiseResponse;
8185
};

packages/open-next/src/overrides/wrappers/dummy.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import type { InternalEvent, StreamCreator } from "types/open-next";
1+
import type { InternalEvent, StreamCreator, WaitUntil } from "types/open-next";
22
import type { Wrapper, WrapperHandler } from "types/overrides";
33

44
const dummyWrapper: WrapperHandler = async (handler, converter) => {
5-
return async (event: InternalEvent, responseStream?: StreamCreator) => {
6-
return await handler(event, responseStream);
5+
return async (
6+
event: InternalEvent,
7+
options?: { streamCreator?: StreamCreator; waitUntil?: WaitUntil },
8+
) => {
9+
return await handler(event, options);
710
};
811
};
912

packages/open-next/src/overrides/wrappers/express-dev.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ const wrapper: WrapperHandler = async (handler, converter) => {
1313

1414
app.all("/_next/image", async (req, res) => {
1515
const internalEvent = await converter.convertFrom(req);
16-
const _res: StreamCreator = {
16+
const streamCreator: StreamCreator = {
1717
writeHeaders: (prelude) => {
1818
res.writeHead(prelude.statusCode, prelude.headers);
1919
return res;
2020
},
2121
};
22-
await imageHandler(internalEvent, _res);
22+
await imageHandler(internalEvent, { streamCreator });
2323
});
2424

2525
app.all("*paths", async (req, res) => {
2626
const internalEvent = await converter.convertFrom(req);
27-
const _res: StreamCreator = {
27+
const streamCreator: StreamCreator = {
2828
writeHeaders: (prelude) => {
2929
res.writeHead(prelude.statusCode, prelude.headers);
3030
return res;
3131
},
3232
onFinish: () => {},
3333
};
34-
await handler(internalEvent, _res);
34+
await handler(internalEvent, { streamCreator });
3535
});
3636

3737
const server = app.listen(

0 commit comments

Comments
 (0)