fix(process launcher): use spawnSync to cleanup synchronously (#13769)

This allows us to use the full retry logic of rimraf in the `onexit` handler.
Note this is already covered by failing on Windows test
`should remove temp dir on process.exit`.
This commit is contained in:
Dmitry Gozman 2022-04-27 15:01:30 +01:00 committed by GitHub
parent bc6f8e1f20
commit dab2384b0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 7 deletions

View File

@ -29,6 +29,7 @@
"./lib/utils/manualPromise": "./lib/utils/manualPromise.js",
"./lib/utils/multimap": "./lib/utils/multimap.js",
"./lib/utils/processLauncher": "./lib/utils/processLauncher.js",
"./lib/utils/processLauncherCleanupEntrypoint": "./lib/utils/processLauncherCleanupEntrypoint.js",
"./lib/utils/spawnAsync": "./lib/utils/spawnAsync.js",
"./lib/utils/stackTrace": "./lib/utils/stackTrace.js",
"./lib/utils/timeoutRunner": "./lib/utils/timeoutRunner.js",

View File

@ -17,10 +17,10 @@
import * as childProcess from 'child_process';
import * as readline from 'readline';
import * as path from 'path';
import { eventsHelper } from './eventsHelper';
import { isUnderTest } from './';
import { removeFolders } from './fileUtils';
import { rimraf } from '../utilsBundle';
export type Env = {[key: string]: string | number | boolean | undefined};
@ -191,12 +191,13 @@ export async function launchProcess(options: LaunchProcessOptions): Promise<Laun
function killProcessAndCleanup() {
killProcess();
options.log(`[pid=${spawnedProcess.pid || 'N/A'}] starting temporary directories cleanup`);
for (const dir of options.tempDirectories) {
try {
rimraf.sync(dir, { maxBusyTries: 10 });
} catch (e) {
options.log(`[pid=${spawnedProcess.pid || 'N/A'}] exception while removing ${dir}: ${e}`);
}
if (options.tempDirectories.length) {
const cleanupProcess = childProcess.spawnSync(process.argv0, [path.join(__dirname, 'processLauncherCleanupEntrypoint.js'), ...options.tempDirectories]);
const [stdout, stderr] = [cleanupProcess.stdout.toString(), cleanupProcess.stderr.toString()];
if (stdout)
options.log(`[pid=${spawnedProcess.pid || 'N/A'}] ${stdout}`);
if (stderr)
options.log(`[pid=${spawnedProcess.pid || 'N/A'}] ${stderr}`);
}
options.log(`[pid=${spawnedProcess.pid || 'N/A'}] finished temporary directories cleanup`);
}

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { removeFolders } from './fileUtils';
(async () => {
const dirs = process.argv.slice(2);
const errors = await removeFolders(dirs);
for (let i = 0; i < dirs.length; ++i) {
if (errors[i]) {
// eslint-disable-next-line no-console
console.error(`exception while removing ${dirs[i]}: ${errors[i]}`);
}
}
})();