Skip to content

Commit

Permalink
refactor(swc/trace): adjust teardown
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj committed Apr 28, 2022
1 parent 9c932b9 commit 05126e8
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 48 deletions.
5 changes: 3 additions & 2 deletions packages/next-swc/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/next/build/index.ts
Expand Up @@ -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
Expand Down Expand Up @@ -2134,6 +2135,7 @@ export default async function build(

// Ensure all traces are flushed before finishing the command
await flushAllTraces()
teardownTraceSubscriber()

return buildResult
}
Expand Down
5 changes: 4 additions & 1 deletion packages/next/build/output/store.ts
Expand Up @@ -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 =
Expand Down Expand Up @@ -100,6 +100,7 @@ store.subscribe((state) => {

// Ensure traces are flushed after each compile in development mode
flushAllTraces()
teardownTraceSubscriber()
return
}

Expand All @@ -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
}

Expand All @@ -141,4 +143,5 @@ store.subscribe((state) => {
)
// Ensure traces are flushed after each compile in development mode
flushAllTraces()
teardownTraceSubscriber()
})
1 change: 1 addition & 0 deletions packages/next/build/swc/index.d.ts
Expand Up @@ -6,3 +6,4 @@ export function minifySync(src: string, options: any): string
export function bundle(options: any): Promise<any>
export function parse(src: string, options: any): any
export function initCustomTraceSubscriber(traceFileName?: string): void
export function teardownTraceSubscriber(): void
39 changes: 24 additions & 15 deletions packages/next/build/swc/index.js
Expand Up @@ -9,6 +9,7 @@ const triples = platformArchTriples[PlatformName][ArchName] || []

let nativeBindings
let wasmBindings
let swcTraceFlushGuard

async function loadBindings() {
let attempts = []
Expand Down Expand Up @@ -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
}
}
}
})()
36 changes: 6 additions & 30 deletions packages/next/build/webpack-config.ts
Expand Up @@ -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')
Expand Down Expand Up @@ -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`)
)
}

Expand Down Expand Up @@ -498,7 +474,7 @@ export default async function getBaseWebpackConfig(
}

const defaultLoaders = {
babel: getBabelOrSwcLoader(false),
babel: getBabelOrSwcLoader(),
}

const rawPageExtensions = hasServerComponents
Expand Down Expand Up @@ -1251,7 +1227,7 @@ export default async function getBaseWebpackConfig(
{
...codeCondition,
issuerLayer: 'middleware',
use: getBabelOrSwcLoader(true),
use: getBabelOrSwcLoader(),
},
{
...codeCondition,
Expand Down

0 comments on commit 05126e8

Please sign in to comment.