Skip to content

Commit f81b6d5

Browse files
ijjkTimer
authored andcommitted
Replace worker-farm with jest-worker (#8496)
* Replace worker-farm with jest-worker * Apply suggestions from code review Co-Authored-By: Joe Haddad <[email protected]> * Remove semaphores on top of jest-worker, unwind terser worker, and remove extra error log
1 parent 2c7b4d8 commit f81b6d5

File tree

6 files changed

+50
-111
lines changed

6 files changed

+50
-111
lines changed

packages/next/build/index.ts

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { Sema } from 'async-sema'
21
import chalk from 'chalk'
32
import fs from 'fs'
43
import mkdirpOrig from 'mkdirp'
@@ -15,7 +14,7 @@ import loadConfig, {
1514
import nanoid from 'next/dist/compiled/nanoid/index.js'
1615
import path from 'path'
1716
import { promisify } from 'util'
18-
import workerFarm from 'worker-farm'
17+
import Worker from 'jest-worker'
1918

2019
import formatWebpackMessages from '../client/dev/error-overlay/format-webpack-messages'
2120
import { recursiveDelete } from '../lib/recursive-delete'
@@ -204,16 +203,10 @@ export default async function build(dir: string, conf = null): Promise<void> {
204203

205204
process.env.NEXT_PHASE = PHASE_PRODUCTION_BUILD
206205

207-
const staticCheckSema = new Sema(config.experimental.cpus, {
208-
capacity: pageKeys.length,
206+
const staticCheckWorkers = new Worker(staticCheckWorker, {
207+
numWorkers: config.experimental.cpus,
208+
enableWorkerThreads: true,
209209
})
210-
const staticCheckWorkers = workerFarm(
211-
{
212-
maxConcurrentWorkers: config.experimental.cpus,
213-
},
214-
staticCheckWorker,
215-
['default']
216-
)
217210

218211
await Promise.all(
219212
pageKeys.map(async page => {
@@ -268,17 +261,10 @@ export default async function build(dir: string, conf = null): Promise<void> {
268261

269262
if (nonReservedPage) {
270263
try {
271-
await staticCheckSema.acquire()
272-
const result: any = await new Promise((resolve, reject) => {
273-
staticCheckWorkers.default(
274-
{ serverBundle, runtimeEnvConfig },
275-
(error: Error | null, result: any) => {
276-
if (error) return reject(error)
277-
resolve(result || {})
278-
}
279-
)
264+
let result: any = await (staticCheckWorkers as any).default({
265+
serverBundle,
266+
runtimeEnvConfig,
280267
})
281-
staticCheckSema.release()
282268

283269
if (result.isHybridAmp) {
284270
hybridAmpPages.add(page)
@@ -293,15 +279,13 @@ export default async function build(dir: string, conf = null): Promise<void> {
293279
} catch (err) {
294280
if (err.message !== 'INVALID_DEFAULT_EXPORT') throw err
295281
invalidPages.add(page)
296-
staticCheckSema.release()
297282
}
298283
}
299284

300285
pageInfos.set(page, { size, chunks, serverBundle, static: isStatic })
301286
})
302287
)
303-
304-
workerFarm.end(staticCheckWorkers)
288+
staticCheckWorkers.end()
305289

306290
if (invalidPages.size > 0) {
307291
throw new Error(

packages/next/build/static-checker.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import { isPageStatic } from './utils'
22

3-
export default function worker(
4-
options: any,
5-
callback: (err: Error | null, data?: any) => void
6-
) {
7-
try {
8-
const { serverBundle, runtimeEnvConfig } = options || ({} as any)
9-
const result = isPageStatic(serverBundle, runtimeEnvConfig)
10-
callback(null, result)
11-
} catch (error) {
12-
callback(error)
13-
}
3+
export default function worker(options: {
4+
serverBundle: string
5+
runtimeEnvConfig: any
6+
}) {
7+
const { serverBundle, runtimeEnvConfig } = options || ({} as any)
8+
return isPageStatic(serverBundle, runtimeEnvConfig)
149
}
Lines changed: 24 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { join } from 'path'
22
import minify from './minify'
33
import { promisify } from 'util'
4-
import workerFarm from 'worker-farm'
4+
import Worker from 'jest-worker'
55
import { writeFile, readFile } from 'fs'
6-
import serialize from 'serialize-javascript'
7-
import { Sema } from 'async-sema'
86
import mkdirp from 'mkdirp'
97

10-
const worker = require.resolve('./worker')
8+
const worker = require.resolve('./minify')
119
const writeFileP = promisify(writeFile)
1210
const readFileP = promisify(readFile)
1311

@@ -16,11 +14,9 @@ export default class TaskRunner {
1614
if (cache) {
1715
mkdirp.sync((this.cacheDir = join(distDir, 'cache', 'next-minifier')))
1816
}
19-
2017
// In some cases cpus() returns undefined
2118
// https://github.com/nodejs/node/issues/19022
2219
this.maxConcurrentWorkers = cpus
23-
this.sema = new Sema(cpus * 3)
2420
}
2521

2622
run(tasks, callback) {
@@ -31,36 +27,18 @@ export default class TaskRunner {
3127
}
3228

3329
if (this.maxConcurrentWorkers > 1) {
34-
const workerOptions =
35-
process.platform === 'win32'
36-
? {
37-
maxConcurrentWorkers: this.maxConcurrentWorkers,
38-
maxConcurrentCallsPerWorker: 1,
39-
}
40-
: { maxConcurrentWorkers: this.maxConcurrentWorkers }
41-
this.workers = workerFarm(workerOptions, worker)
42-
this.boundWorkers = (options, cb) => {
43-
try {
44-
this.workers(serialize(options), cb)
45-
} catch (error) {
46-
// worker-farm can fail with ENOMEM or something else
47-
cb(error)
48-
}
49-
}
30+
this.workers = new Worker(worker, {
31+
enableWorkerThreads: true,
32+
numWorkers: this.maxConcurrentWorkers,
33+
})
34+
this.boundWorkers = options => this.workers.default(options)
5035
} else {
51-
this.boundWorkers = (options, cb) => {
52-
try {
53-
cb(null, minify(options))
54-
} catch (error) {
55-
cb(error)
56-
}
57-
}
36+
this.boundWorkers = async options => minify(options)
5837
}
5938

6039
let toRun = tasks.length
6140
const results = []
6241
const step = (index, data) => {
63-
this.sema.release()
6442
toRun -= 1
6543
results[index] = data
6644

@@ -71,37 +49,33 @@ export default class TaskRunner {
7149

7250
tasks.forEach((task, index) => {
7351
const cachePath = this.cacheDir && join(this.cacheDir, task.cacheKey)
74-
75-
const enqueue = () => {
76-
this.boundWorkers(task, (error, data) => {
77-
const result = error ? { error } : data
52+
const enqueue = async () => {
53+
try {
54+
const result = await this.boundWorkers(task)
7855
const done = () => step(index, result)
79-
80-
if (this.cacheDir && !result.error) {
81-
writeFileP(cachePath, JSON.stringify(data), 'utf8')
56+
if (cachePath) {
57+
writeFileP(cachePath, JSON.stringify(result), 'utf8')
8258
.then(done)
8359
.catch(done)
84-
} else {
85-
done()
8660
}
87-
})
61+
} catch (error) {
62+
step(index, { error })
63+
}
8864
}
8965

90-
this.sema.acquire().then(() => {
91-
if (this.cacheDir) {
92-
readFileP(cachePath, 'utf8')
93-
.then(data => step(index, JSON.parse(data)))
94-
.catch(() => enqueue())
95-
} else {
96-
enqueue()
97-
}
98-
})
66+
if (this.cacheDir) {
67+
readFileP(cachePath, 'utf8')
68+
.then(data => step(index, JSON.parse(data)))
69+
.catch(() => enqueue())
70+
} else {
71+
enqueue()
72+
}
9973
})
10074
}
10175

10276
exit() {
10377
if (this.workers) {
104-
workerFarm.end(this.workers)
78+
this.workers.end()
10579
}
10680
}
10781
}

packages/next/build/webpack/plugins/terser-webpack-plugin/src/worker.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

packages/next/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"find-up": "4.0.0",
8181
"fork-ts-checker-webpack-plugin": "1.3.4",
8282
"fresh": "0.5.2",
83+
"jest-worker": "24.9.0",
8384
"launch-editor": "2.2.1",
8485
"loader-utils": "1.2.3",
8586
"mkdirp": "0.5.1",
@@ -88,7 +89,6 @@
8889
"prop-types-exact": "1.2.0",
8990
"react-error-overlay": "5.1.6",
9091
"react-is": "16.8.6",
91-
"serialize-javascript": "1.7.0",
9292
"source-map": "0.6.1",
9393
"string-hash": "1.1.3",
9494
"strip-ansi": "5.2.0",
@@ -101,8 +101,7 @@
101101
"webpack": "4.39.0",
102102
"webpack-dev-middleware": "3.7.0",
103103
"webpack-hot-middleware": "2.25.0",
104-
"webpack-sources": "1.3.0",
105-
"worker-farm": "1.7.0"
104+
"webpack-sources": "1.3.0"
106105
},
107106
"peerDependencies": {
108107
"react": "^16.6.0",

yarn.lock

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8345,6 +8345,14 @@ jest-watcher@^24.8.0:
83458345
jest-util "^24.8.0"
83468346
string-length "^2.0.0"
83478347

8348+
8349+
version "24.9.0"
8350+
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
8351+
integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==
8352+
dependencies:
8353+
merge-stream "^2.0.0"
8354+
supports-color "^6.1.0"
8355+
83488356
jest-worker@^24.6.0:
83498357
version "24.6.0"
83508358
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3"
@@ -12315,7 +12323,7 @@ sentence-case@^2.1.0:
1231512323
no-case "^2.2.0"
1231612324
upper-case-first "^1.1.2"
1231712325

12318-
serialize-javascript@1.7.0, serialize-javascript@^1.7.0:
12326+
serialize-javascript@^1.7.0:
1231912327
version "1.7.0"
1232012328
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65"
1232112329
integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==
@@ -14267,7 +14275,7 @@ wordwrap@~1.0.0:
1426714275
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
1426814276
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
1426914277

14270-
worker-farm@1.7.0, worker-farm@^1.7.0:
14278+
worker-farm@^1.7.0:
1427114279
version "1.7.0"
1427214280
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
1427314281
integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==

0 commit comments

Comments
 (0)