Skip to content

Commit

Permalink
Kill existing vet/lint processes before starting new ones (golang#1330)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramya-rao-a authored Nov 11, 2017
1 parent 0eb7308 commit 708ef1a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
21 changes: 18 additions & 3 deletions src/goLint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,27 @@ export function goLint(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigurat
args.push('./...');
}

return runTool(
if (running) {
tokenSource.cancel();
}

running = true;
const lintPromise = runTool(
args,
(lintWorkspace && currentWorkspace) ? currentWorkspace : path.dirname(fileUri.fsPath),
'warning',
false,
lintTool,
lintEnv
);
lintEnv,
false,
tokenSource.token
).then((result) => {
running = false;
return result;
});

return lintPromise;
}

let tokenSource = new vscode.CancellationTokenSource();
let running = false;
21 changes: 18 additions & 3 deletions src/goVet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,27 @@ export function goVet(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigurati
let vetArgs = vetFlags.length ? ['tool', 'vet', ...vetFlags, '.'] : ['vet', './...'];
let currentWorkspace = getWorkspaceFolderPath(fileUri);

return runTool(
if (running) {
tokenSource.cancel();
}

running = true;
const vetPromise = runTool(
vetArgs,
(vetWorkspace && currentWorkspace) ? currentWorkspace : path.dirname(fileUri.fsPath),
'warning',
true,
null,
vetEnv
);
vetEnv,
false,
tokenSource.token
).then((result) => {
running = false;
return result;
});

return vetPromise;
}

let tokenSource = new vscode.CancellationTokenSource();
let running = false;
32 changes: 30 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,11 +499,19 @@ export interface ICheckResult {
* @param toolName The name of the Go tool to run. If none is provided, the go runtime itself is used
* @param printUnexpectedOutput If true, then output that doesnt match expected format is printed to the output channel
*/
export function runTool(args: string[], cwd: string, severity: string, useStdErr: boolean, toolName: string, env: any, printUnexpectedOutput?: boolean): Promise<ICheckResult[]> {
export function runTool(args: string[], cwd: string, severity: string, useStdErr: boolean, toolName: string, env: any, printUnexpectedOutput: boolean, token?: vscode.CancellationToken): Promise<ICheckResult[]> {
let goRuntimePath = getGoRuntimePath();
let cmd = toolName ? getBinPath(toolName) : goRuntimePath;
let p: cp.ChildProcess;
if (token) {
token.onCancellationRequested(() => {
if (p) {
killTree(p.pid);
}
});
}
return new Promise((resolve, reject) => {
cp.execFile(cmd, args, { env: env, cwd: cwd }, (err, stdout, stderr) => {
p = cp.execFile(cmd, args, { env: env, cwd: cwd }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
// Since the tool is run on save which can be frequent
Expand Down Expand Up @@ -657,4 +665,24 @@ export function killProcess(p: cp.ChildProcess) {

}
}
}

export function killTree(processId: number): void {
if (process.platform === 'win32') {
const TASK_KILL = 'C:\\Windows\\System32\\taskkill.exe';

// when killing a process in Windows its child processes are *not* killed but become root processes.
// Therefore we use TASKKILL.EXE
try {
cp.execSync(`${TASK_KILL} /F /T /PID ${processId}`);
} catch (err) {
}
} else {
// on linux and OS X we kill all direct and indirect child processes as well
try {
const cmd = path.join(__dirname, '../../../scripts/terminateProcess.sh');
cp.spawnSync(cmd, [processId.toString()]);
} catch (err) {
}
}
}

0 comments on commit 708ef1a

Please sign in to comment.