Skip to content

Commit

Permalink
Fix race condition on terminal open. Refs #848
Browse files Browse the repository at this point in the history
  • Loading branch information
badsyntax committed Mar 6, 2021
1 parent f8d9731 commit 9dfde86
Show file tree
Hide file tree
Showing 18 changed files with 141 additions and 184 deletions.
7 changes: 6 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ subprojects {

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${protocVersion}"
// for apple m1, please add protoc_platform=osx-x86_64 in $HOME/.gradle/gradle.properties
if (project.hasProperty('protoc_platform')) {
artifact = "com.google.protobuf:protoc:${protocVersion}:${protoc_platform}"
} else {
artifact = "com.google.protobuf:protoc:${protocVersion}:${protoc_platform}"
}
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion extension/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,12 @@ task npmInstall(type: CrossPlatformExec) {
inputs.file('package-lock.json').withPathSensitivity(PathSensitivity.RELATIVE)
outputs.dir('node_modules')
outputs.cacheIf { true }
commandLine 'npm', 'install'
// for apple m1, please add npm_arch=x64 in $HOME/.gradle/gradle.properties
if (project.hasProperty('npm_arch')) {
commandLine 'npm', "--target_arch=${npm_arch}", 'install'
} else {
commandLine 'npm', 'install'
}
}

task lint(type: CrossPlatformExec) {
Expand Down
6 changes: 3 additions & 3 deletions extension/package-lock.json

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

2 changes: 1 addition & 1 deletion extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@
"fs-extra": "^9.0.1",
"get-port": "^5.1.1",
"google-protobuf": "^3.13.0",
"grpc-tools": "^1.9.1",
"grpc-tools": "^1.10.0",
"minimatch": "^3.0.4",
"mocha": "^8.2.0",
"prettier": "^2.1.2",
Expand Down
33 changes: 29 additions & 4 deletions extension/src/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { Commands } from './commands/Commands';
import {
getConfigIsDebugEnabled,
getConfigFocusTaskInExplorer,
getConfigReuseTerminals,
} from './util/config';
import { FileWatcher } from './util/FileWatcher';

Expand All @@ -59,6 +60,7 @@ export class Extension {
private readonly gradleTasksTreeDataProvider: GradleTasksTreeDataProvider;
private readonly api: Api;
private readonly commands: Commands;
private recentTerminal?: vscode.Terminal;

public constructor(private readonly context: vscode.ExtensionContext) {
const loggingChannel = vscode.window.createOutputChannel('Gradle Tasks');
Expand Down Expand Up @@ -87,7 +89,6 @@ export class Extension {
this.rootProjectsStore = new RootProjectsStore();
this.gradleTaskProvider = new GradleTaskProvider(
this.rootProjectsStore,
this.taskTerminalsStore,
this.client
);
this.taskProvider = vscode.tasks.registerTaskProvider(
Expand Down Expand Up @@ -123,7 +124,6 @@ export class Extension {
this.pinnedTasksStore,
this.rootProjectsStore,
this.gradleTaskProvider,
this.taskTerminalsStore,
this.icons,
this.client
);
Expand Down Expand Up @@ -221,10 +221,32 @@ export class Extension {

private handleTaskEvents(): void {
this.gradleTaskManager.onDidStartTask(async (task: vscode.Task) => {
const reuseTerminals = getConfigReuseTerminals();

const definition = task.definition as GradleTaskDefinition;

// Close previously opened task terminals
this.taskTerminalsStore.disposeTaskTerminals(
task.definition as GradleTaskDefinition,
reuseTerminals
);
// Add this task terminal to the store
if (this.recentTerminal) {
const terminalTaskName = this.recentTerminal.name.replace(
'Task - ',
''
);
if (terminalTaskName === definition.script) {
this.taskTerminalsStore.addEntry(
terminalTaskName,
this.recentTerminal
);
}
}

if (this.gradleTasksTreeView.visible && getConfigFocusTaskInExplorer()) {
await focusTaskInGradleTasksTree(task, this.gradleTasksTreeView);
}
const definition = task.definition as GradleTaskDefinition;
this.recentTasksStore.addEntry(definition.id, definition.args);
await vscode.commands.executeCommand(COMMAND_RENDER_TASK, task);
});
Expand Down Expand Up @@ -284,7 +306,10 @@ export class Extension {
vscode.window.onDidCloseTerminal((terminal: vscode.Terminal) => {
this.taskTerminalsStore.removeTerminal(terminal);
}),
vscode.workspace.onDidChangeWorkspaceFolders(() => this.refresh())
vscode.workspace.onDidChangeWorkspaceFolders(() => this.refresh()),
vscode.window.onDidOpenTerminal((terminal: vscode.Terminal) => {
this.recentTerminal = terminal;
})
);
}

Expand Down
73 changes: 41 additions & 32 deletions extension/src/client/GradleClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,25 +338,30 @@ export class GradleClient implements vscode.Disposable {
const request = new CancelBuildRequest();
request.setCancellationKey(cancellationKey);
try {
const reply: CancelBuildReply = await new Promise((resolve, reject) => {
this.grpcClient!.cancelBuild(
request,
(
err: grpc.ServiceError | null,
cancelRunBuildReply: CancelBuildReply | undefined
) => {
if (err) {
reject(err);
} else {
resolve(cancelRunBuildReply);
const reply: CancelBuildReply | undefined = await new Promise(
(resolve, reject) => {
console.log('cancel build');
this.grpcClient!.cancelBuild(
request,
(
err: grpc.ServiceError | null,
cancelRunBuildReply: CancelBuildReply | undefined
) => {
if (err) {
reject(err);
} else {
resolve(cancelRunBuildReply);
}
}
}
);
});
logger.info('Cancel build:', reply.getMessage());
);
}
);
if (reply) {
logger.info('Cancel build:', reply.getMessage());

if (!reply.getBuildRunning() && task) {
removeCancellingTask(task);
if (!reply.getBuildRunning() && task) {
removeCancellingTask(task);
}
}
} catch (err) {
logger.error('Error cancelling build:', err.details || err.message);
Expand All @@ -367,22 +372,26 @@ export class GradleClient implements vscode.Disposable {
this.statusBarItem.hide();
const request = new CancelBuildsRequest();
try {
const reply: CancelBuildsReply = await new Promise((resolve, reject) => {
this.grpcClient!.cancelBuilds(
request,
(
err: grpc.ServiceError | null,
cancelRunBuildsReply: CancelBuildsReply | undefined
) => {
if (err) {
reject(err);
} else {
resolve(cancelRunBuildsReply);
const reply: CancelBuildsReply | undefined = await new Promise(
(resolve, reject) => {
this.grpcClient!.cancelBuilds(
request,
(
err: grpc.ServiceError | null,
cancelRunBuildsReply: CancelBuildsReply | undefined
) => {
if (err) {
reject(err);
} else {
resolve(cancelRunBuildsReply);
}
}
}
);
});
logger.info('Cancel builds:', reply.getMessage());
);
}
);
if (reply) {
logger.info('Cancel builds:', reply.getMessage());
}
} catch (err) {
logger.error('Error cancelling builds:', err.details || err.message);
}
Expand Down
25 changes: 25 additions & 0 deletions extension/src/stores/TaskTerminalsStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as vscode from 'vscode';
import { TaskId } from './types';
import { StoreMapSet } from '.';
import { GradleTaskDefinition } from '../tasks';
import { ReuseTerminalsValue } from '../util/config';

export class TaskTerminalsStore extends StoreMapSet<TaskId, vscode.Terminal> {
removeTerminal(terminal: vscode.Terminal): void {
Expand All @@ -16,4 +18,27 @@ export class TaskTerminalsStore extends StoreMapSet<TaskId, vscode.Terminal> {
});
this.fireOnDidChange(null);
}

disposeTaskTerminals(
definition: GradleTaskDefinition,
reuseTerminals: ReuseTerminalsValue
): void {
if (reuseTerminals === 'task') {
const previousTerminals = this.get(definition.script);
if (previousTerminals) {
for (const previousTerminal of previousTerminals.values()) {
previousTerminal.dispose();
}
previousTerminals.clear();
}
} else if (reuseTerminals === 'all') {
const store = this.getData();
for (const taskTerminals of store.values()) {
for (const previousTerminal of taskTerminals.values()) {
previousTerminal.dispose();
}
taskTerminals.clear();
}
}
}
}
16 changes: 4 additions & 12 deletions extension/src/tasks/GradleTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { GradleTaskDefinition } from '.';
import { logger } from '../logger';
import { createTaskFromDefinition, loadTasksForProjectRoots } from './taskUtil';
import { TaskId } from '../stores/types';
import { RootProjectsStore, TaskTerminalsStore } from '../stores';
import { RootProjectsStore } from '../stores';
import { RootProject } from '../rootProject/RootProject';
import { GradleClient } from '../client';
import { getConfigJavaDebug, getConfigReuseTerminals } from '../util/config';
import { getConfigJavaDebug } from '../util/config';
import { EventWaiter } from '../util/EventWaiter';

export class GradleTaskProvider
Expand All @@ -24,7 +24,6 @@ export class GradleTaskProvider

constructor(
private readonly rootProjectsStore: RootProjectsStore,
private readonly taskTerminalsStore: TaskTerminalsStore,
private readonly client: GradleClient
) {}

Expand Down Expand Up @@ -66,13 +65,10 @@ export class GradleTaskProvider
vscode.Uri.file(gradleTaskDefinition.projectFolder),
javaDebug
);
const reuseTerminals = getConfigReuseTerminals();
return createTaskFromDefinition(
this.taskTerminalsStore,
gradleTaskDefinition,
rootProject,
this.client,
reuseTerminals
this.client
);
}

Expand All @@ -91,11 +87,7 @@ export class GradleTaskProvider
return Promise.resolve(this.cachedTasks);
}

this.loadTasksPromise = loadTasksForProjectRoots(
this.taskTerminalsStore,
this.client,
folders
)
this.loadTasksPromise = loadTasksForProjectRoots(this.client, folders)
.then(
(tasks) => {
this.cachedTasks = tasks;
Expand Down
Loading

0 comments on commit 9dfde86

Please sign in to comment.