[be][snap] Warm up workers when in watch + filter mode
Mofei Zhang committed
Mar 11, 2024 at 13:55 UTC
c84b81797298cccc95e653ba7387063ceee7268a
2 files changed
+45
-21
compiler/packages/snap/src/runner-watch.ts
+15
-21
@@ -114,7 +114,6 @@ function subscribeFixtures(
114
onChange: (state: RunnerState) => void
115
) {
116
// Watch the fixtures directory for changes
117
- /* const fileSubscription = */
117
watcher.subscribe(FIXTURES_PATH, async (err, _events) => {
118
if (err) {
119
console.error(err);
@@ -127,6 +126,7 @@ function subscribeFixtures(
126
const isRealUpdate = performance.now() - state.lastUpdate > 5000;
127
if (isRealUpdate) {
128
// Fixtures changed, re-run tests
129
+ state.mode.action = RunnerAction.Test;
130
onChange(state);
131
}
132
});
@@ -136,23 +136,20 @@ function subscribeFilterFile(
136
state: RunnerState,
137
onChange: (state: RunnerState) => void
138
) {
139
- const filterSubscription = watcher.subscribe(
140
- process.cwd(),
141
- async (err, events) => {
142
- if (err) {
143
- console.error(err);
144
- process.exit(1);
145
- } else if (
146
- events.findIndex((event) => event.path.includes(FILTER_FILENAME)) !== -1
147
- ) {
148
- state.filter = await readTestFilter();
149
- if (state.mode.filter) {
150
- state.mode.action = RunnerAction.Test;
151
- onChange(state);
152
- }
139
+ watcher.subscribe(process.cwd(), async (err, events) => {
140
+ if (err) {
141
+ console.error(err);
142
+ process.exit(1);
143
+ } else if (
144
+ events.findIndex((event) => event.path.includes(FILTER_FILENAME)) !== -1
145
+ ) {
146
+ state.filter = await readTestFilter();
147
+ if (state.mode.filter) {
148
+ state.mode.action = RunnerAction.Test;
149
+ onChange(state);
150
}
151
}
155
- );
152
+ });
153
}
154
155
function subscribeTsc(
@@ -172,11 +169,7 @@ function subscribeTsc(
169
state.compilerVersion++;
170
}
171
state.isCompilerBuildValid = isSuccess;
175
- if (state.filter) {
176
- state.mode.action = RunnerAction.Test;
177
- } else {
178
- state.mode.action = RunnerAction.Test;
179
- }
172
+ state.mode.action = RunnerAction.Test;
173
onChange(state);
174
}
175
);
@@ -194,6 +187,7 @@ function subscribeKeyEvents(
187
process.exit(0);
188
} else if (key.name === "f") {
189
state.mode.filter = !state.mode.filter;
190
+ state.mode.action = RunnerAction.Test;
191
} else {
192
// any other key re-runs tests
193
state.mode.action = RunnerAction.Test;
compiler/packages/snap/src/runner.ts
+30
@@ -6,6 +6,7 @@
6
*/
7
8
import { Worker } from "jest-worker";
9
+import { cpus } from "os";
10
import process from "process";
11
import * as readline from "readline";
12
import ts from "typescript";
@@ -23,6 +24,7 @@ import {
24
import * as runnerWorker from "./runner-worker";
25
26
const WORKER_PATH = require.resolve("./runner-worker.js");
27
+const NUM_WORKERS = cpus().length - 1;
28
29
readline.emitKeypressEvents(process.stdin);
30
@@ -163,12 +165,40 @@ async function onChange(
165
export async function main(opts: RunnerOptions): Promise<void> {
166
const worker: Worker & typeof runnerWorker = new Worker(WORKER_PATH, {
167
enableWorkerThreads: opts.workerThreads,
168
+ numWorkers: NUM_WORKERS,
169
}) as any;
170
worker.getStderr().pipe(process.stderr);
171
worker.getStdout().pipe(process.stdout);
172
173
if (opts.watch) {
174
makeWatchRunner((state) => onChange(worker, state), opts.filter);
175
+ if (opts.filter) {
176
+ /**
177
+ * Warm up wormers when in watch mode. Loading the Forget babel plugin
178
+ * and all of its transitive dependencies takes 1-3s (per worker) on a M1.
179
+ * As jest-worker dispatches tasks using a round-robin strategy, we can
180
+ * avoid an additional 1-3s wait on the first num_workers runs by warming
181
+ * up workers eagerly.
182
+ */
183
+ for (let i = 0; i < NUM_WORKERS - 1; i++) {
184
+ worker.transformFixture(
185
+ {
186
+ fixturePath: "tmp",
187
+ snapshotPath: "./tmp.expect.md",
188
+ inputPath: "./tmp.js",
189
+ input: `
190
+ function Foo(props) {
191
+ return identity(props);
192
+ }
193
+ `,
194
+ snapshot: null,
195
+ },
196
+ 0,
197
+ false,
198
+ false
199
+ );
200
+ }
201
+ }
202
} else {
203
// Non-watch mode. For simplicity we re-use the same watchSrc() function.
204
// After the first build completes run tests and exit