From 05126e80eb3a65ea765f4424d4e25f268890cace Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Fri, 22 Apr 2022 10:41:57 -0700 Subject: [PATCH] refactor(swc/trace): adjust teardown --- packages/next-swc/Cargo.lock | 5 ++-- packages/next/build/index.ts | 2 ++ packages/next/build/output/store.ts | 5 +++- packages/next/build/swc/index.d.ts | 1 + packages/next/build/swc/index.js | 39 ++++++++++++++++----------- packages/next/build/webpack-config.ts | 36 +++++-------------------- 6 files changed, 40 insertions(+), 48 deletions(-) diff --git a/packages/next-swc/Cargo.lock b/packages/next-swc/Cargo.lock index 045b129c28ba..e42f09ade5e5 100644 --- a/packages/next-swc/Cargo.lock +++ b/packages/next-swc/Cargo.lock @@ -2884,8 +2884,9 @@ dependencies = [ [[package]] name = "tracing-chrome" -version = "0.6.0" -source = "git+https://github.com/kwonoj/tracing-chrome?rev=0dd9d6c9e0f74f43993b58560f4ac0103e058df8#0dd9d6c9e0f74f43993b58560f4ac0103e058df8" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb13184244c7cd22758b79e7c993c515ad67a8e730edcb7e05fe7bcabb283c7" dependencies = [ "json", "tracing", diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index c230b63cf834..61c5b411fde2 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -113,6 +113,7 @@ import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack' import { recursiveCopy } from '../lib/recursive-copy' import { shouldUseReactRoot } from '../server/config' import { recursiveReadDir } from '../lib/recursive-readdir' +import { teardownTraceSubscriber } from './swc' export type SsgRoute = { initialRevalidateSeconds: number | false @@ -2134,6 +2135,7 @@ export default async function build( // Ensure all traces are flushed before finishing the command await flushAllTraces() + teardownTraceSubscriber() return buildResult } diff --git a/packages/next/build/output/store.ts b/packages/next/build/output/store.ts index 4c0af9268030..85998dbbd097 100644 --- a/packages/next/build/output/store.ts +++ b/packages/next/build/output/store.ts @@ -2,7 +2,7 @@ import createStore from 'next/dist/compiled/unistore' import stripAnsi from 'next/dist/compiled/strip-ansi' import { flushAllTraces } from '../../trace' import { getUnresolvedModuleFromError } from '../utils' - +import { teardownTraceSubscriber } from '../swc' import * as Log from './log' export type OutputState = @@ -100,6 +100,7 @@ store.subscribe((state) => { // Ensure traces are flushed after each compile in development mode flushAllTraces() + teardownTraceSubscriber() return } @@ -126,6 +127,7 @@ store.subscribe((state) => { Log.warn(state.warnings.join('\n\n')) // Ensure traces are flushed after each compile in development mode flushAllTraces() + teardownTraceSubscriber() return } @@ -141,4 +143,5 @@ store.subscribe((state) => { ) // Ensure traces are flushed after each compile in development mode flushAllTraces() + teardownTraceSubscriber() }) diff --git a/packages/next/build/swc/index.d.ts b/packages/next/build/swc/index.d.ts index f29161247652..5dac4bf84d00 100644 --- a/packages/next/build/swc/index.d.ts +++ b/packages/next/build/swc/index.d.ts @@ -6,3 +6,4 @@ export function minifySync(src: string, options: any): string export function bundle(options: any): Promise export function parse(src: string, options: any): any export function initCustomTraceSubscriber(traceFileName?: string): void +export function teardownTraceSubscriber(): void diff --git a/packages/next/build/swc/index.js b/packages/next/build/swc/index.js index 201248bae04f..b94bbbd37329 100644 --- a/packages/next/build/swc/index.js +++ b/packages/next/build/swc/index.js @@ -9,6 +9,7 @@ const triples = platformArchTriples[PlatformName][ArchName] || [] let nativeBindings let wasmBindings +let swcTraceFlushGuard async function loadBindings() { let attempts = [] @@ -258,31 +259,39 @@ export function getBinaryMetadata() { /** * Initialize trace subscriber to emit traces. * - * Returns an internal object to guard async flush emission if subscriber is initialized, caller should manually - * tear it down via `teardownTraceSubscriber`. */ export const initCustomTraceSubscriber = (() => { - let guard - return (filename) => { - if (!guard) { + if (!swcTraceFlushGuard) { // Wasm binary doesn't support trace emission let bindings = loadNative() - guard = bindings.initCustomTraceSubscriber(filename) + swcTraceFlushGuard = bindings.initCustomTraceSubscriber(filename) } - - return guard } })() +/** + * Teardown swc's trace subscriber if there's an initialized flush guard exists. + * + * This is workaround to amend behavior with process.exit + * (https://github.com/vercel/next.js/blob/4db8c49cc31e4fc182391fae6903fb5ef4e8c66e/packages/next/bin/next.ts#L134=) + * seems preventing napi's cleanup hook execution (https://github.com/swc-project/swc/blob/main/crates/node/src/util.rs#L48-L51=), + * + * instead parent process manually drops guard when process gets signal to exit. + */ export const teardownTraceSubscriber = (() => { - let bindings - - return (guard) => { - if (!bindings && !!guard) { - // Wasm binary doesn't support trace emission - bindings = loadNative() - return bindings.teardownTraceSubscriber(guard) + let flushed = false + return () => { + if (!flushed) { + flushed = true + try { + let bindings = loadNative() + if (swcTraceFlushGuard) { + bindings.teardownTraceSubscriber(swcTraceFlushGuard) + } + } catch (e) { + // Suppress exceptions, this fn allows to fail to load native bindings + } } } })() diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index c171332fe13d..cbe543bc0246 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -87,22 +87,6 @@ const devtoolRevertWarning = execOnce( let loggedSwcDisabled = false let loggedIgnoredCompilerOptions = false -let swcTraceFlushGuard: unknown = null - -/** - * Teardown swc's trace subscriber if there's an initialized flush guard exists. - * - * This is workaround to amend behavior with process.exit - * (https://github.com/vercel/next.js/blob/4db8c49cc31e4fc182391fae6903fb5ef4e8c66e/packages/next/bin/next.ts#L134=) - * seems preventing napi's cleanup hook execution (https://github.com/swc-project/swc/blob/main/crates/node/src/util.rs#L48-L51=), - * - * instead parent process manually drops guard when process gets signal to exit. - */ -process.on('exit', () => { - if (swcTraceFlushGuard) { - require('./swc')?.teardownTraceSubscriber?.(swcTraceFlushGuard) - } -}) function getOptimizedAliases(): { [pkg: string]: string } { const stubWindowFetch = path.join(__dirname, 'polyfills', 'fetch', 'index.js') @@ -451,22 +435,14 @@ export default async function getBaseWebpackConfig( loggedIgnoredCompilerOptions = true } - const getBabelOrSwcLoader = (buildDir: string) => { - if ( - useSWCLoader && - config?.experimental?.swcTraceProfiling && - !swcTraceFlushGuard - ) { + const getBabelOrSwcLoader = () => { + if (useSWCLoader && config?.experimental?.swcTraceProfiling) { // This will init subscribers once only in a single process lifecycle, // even though it can be called multiple times. // Subscriber need to be initialized _before_ any actual swc's call (transform, etcs) // to collect correct trace spans when they are called. - swcTraceFlushGuard = require('./swc')?.initCustomTraceSubscriber?.( - path.join( - buildDir, - config.distDir, - `swc-trace-profile-${Date.now()}.json` - ) + require('./swc')?.initCustomTraceSubscriber?.( + path.join(config.distDir, `swc-trace-profile-${Date.now()}.json`) ) } @@ -498,7 +474,7 @@ export default async function getBaseWebpackConfig( } const defaultLoaders = { - babel: getBabelOrSwcLoader(false), + babel: getBabelOrSwcLoader(), } const rawPageExtensions = hasServerComponents @@ -1251,7 +1227,7 @@ export default async function getBaseWebpackConfig( { ...codeCondition, issuerLayer: 'middleware', - use: getBabelOrSwcLoader(true), + use: getBabelOrSwcLoader(), }, { ...codeCondition,