Skip to content

Commit

Permalink
[unstable_after] compat: use waitUntil from NextRequestHint if no bui…
Browse files Browse the repository at this point in the history
…ltin waitUntil is available
  • Loading branch information
lubieowoce committed May 23, 2024
1 parent e62bc11 commit 1d23c8a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createAsyncLocalStorage } from './async-local-storage'
import type { LifecycleAsyncStorage } from './lifecycle-async-storage.external'

export const lifecycleAsyncStorage: LifecycleAsyncStorage =
createAsyncLocalStorage()
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { AsyncLocalStorage } from 'async_hooks'
// Share the instance module in the next-shared layer
import { lifecycleAsyncStorage } from './lifecycle-async-storage-instance' with { 'turbopack-transition': 'next-shared' }

export interface LifecycleStore {
readonly waitUntil: ((promise: Promise<any>) => void) | undefined
}

export type LifecycleAsyncStorage = AsyncLocalStorage<LifecycleStore>

export { lifecycleAsyncStorage }
6 changes: 6 additions & 0 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ import {
getBuiltinRequestContext,
type WaitUntil,
} from './after/builtin-request-context'
import { lifecycleAsyncStorage } from '../client/components/lifecycle-async-storage.external'

export type FindComponentsResult = {
components: LoadComponentsReturnType
Expand Down Expand Up @@ -1679,6 +1680,11 @@ export default abstract class Server<
return builtinRequestContext.waitUntil
}

const lifecycleStore = lifecycleAsyncStorage.getStore()
if (lifecycleStore) {
return lifecycleStore.waitUntil
}

if (process.env.__NEXT_TEST_MODE) {
// we're in a test, use a no-op.
return Server.noopWaitUntil
Expand Down
22 changes: 19 additions & 3 deletions packages/next/src/server/web/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { getTracer } from '../lib/trace/tracer'
import type { TextMapGetter } from 'next/dist/compiled/@opentelemetry/api'
import { MiddlewareSpan } from '../lib/trace/constants'
import { CloseController } from './web-on-close'
import { getBuiltinRequestContext } from '../after/builtin-request-context'
import { lifecycleAsyncStorage } from '../../client/components/lifecycle-async-storage-instance'

export class NextRequestHint extends NextRequest {
sourcePage: string
Expand Down Expand Up @@ -213,13 +215,14 @@ export async function adapter(
const isMiddleware =
params.page === '/middleware' || params.page === '/src/middleware'

const isAfterEnabled =
params.request.nextConfig?.experimental?.after ??
!!process.env.__NEXT_AFTER

if (isMiddleware) {
// if we're in an edge function, we only get a subset of `nextConfig` (no `experimental`),
// so we have to inject it via DefinePlugin.
// in `next start` this will be passed normally (see `NextNodeServer.runMiddleware`).
const isAfterEnabled =
params.request.nextConfig?.experimental?.after ??
!!process.env.__NEXT_AFTER

let waitUntil: WrapperRenderOpts['waitUntil'] = undefined
let closeController: CloseController | undefined = undefined
Expand Down Expand Up @@ -279,6 +282,19 @@ export async function adapter(
}
)
}

if (isAfterEnabled && !getBuiltinRequestContext()) {
// FIXME(after): unify on this method of passing waitUntil around,
// there's too much variation around this right now
//
// (here, we need to do this with an ALS because if the handler is a NextWebServer,
// there's currently no other way to pass `waitUntil` into it)
return lifecycleAsyncStorage.run(
{ waitUntil: event.waitUntil.bind(event) },
() => params.handler(request, event)
)
}

return params.handler(request, event)
})

Expand Down

0 comments on commit 1d23c8a

Please sign in to comment.