@theia/ai-ide 1.71.0-next.11 → 1.71.0-next.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/workspace-task-provider.d.ts.map +1 -1
- package/lib/browser/workspace-task-provider.js +4 -1
- package/lib/browser/workspace-task-provider.js.map +1 -1
- package/lib/browser/workspace-task-provider.spec.js +90 -1
- package/lib/browser/workspace-task-provider.spec.js.map +1 -1
- package/package.json +22 -22
- package/src/browser/workspace-task-provider.spec.ts +119 -1
- package/src/browser/workspace-task-provider.ts +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-task-provider.d.ts","sourceRoot":"","sources":["../../src/browser/workspace-task-provider.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyB,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlF,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAGpF,qBACa,gBAAiB,YAAW,YAAY;IAGjD,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAE5C,OAAO,IAAI,WAAW;YAgCR,iBAAiB;CAMlC;AAED,qBACa,kBAAmB,YAAW,YAAY;IAGnD,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAG5C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAEpD,OAAO,IAAI,WAAW;YA0BR,aAAa;
|
|
1
|
+
{"version":3,"file":"workspace-task-provider.d.ts","sourceRoot":"","sources":["../../src/browser/workspace-task-provider.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyB,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlF,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAGpF,qBACa,gBAAiB,YAAW,YAAY;IAGjD,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAE5C,OAAO,IAAI,WAAW;YAgCR,iBAAiB;CAMlC;AAED,qBACa,kBAAmB,YAAW,YAAY;IAGnD,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAG5C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAEpD,OAAO,IAAI,WAAW;YA0BR,aAAa;CA6C9B"}
|
|
@@ -103,7 +103,10 @@ let TaskRunnerProvider = class TaskRunnerProvider {
|
|
|
103
103
|
return `Did not find a task for the label: '${args.taskName}'`;
|
|
104
104
|
}
|
|
105
105
|
cancellationToken?.onCancellationRequested(() => {
|
|
106
|
-
|
|
106
|
+
// Only terminate if the task is still running
|
|
107
|
+
if (this.taskService.isTaskRunning(taskInfo.taskId)) {
|
|
108
|
+
this.taskService.terminateTask(taskInfo);
|
|
109
|
+
}
|
|
107
110
|
});
|
|
108
111
|
if (cancellationToken?.isCancellationRequested) {
|
|
109
112
|
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-task-provider.js","sourceRoot":"","sources":["../../src/browser/workspace-task-provider.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"workspace-task-provider.js","sourceRoot":"","sources":["../../src/browser/workspace-task-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,7 +67,8 @@ describe('Workspace Task Provider Cancellation Tests', () => {
|
|
|
67
67
|
terminateTask: async (activeTaskInfo) => {
|
|
68
68
|
// Track termination
|
|
69
69
|
},
|
|
70
|
-
getTerminateSignal: async () => 'SIGTERM'
|
|
70
|
+
getTerminateSignal: async () => 'SIGTERM',
|
|
71
|
+
isTaskRunning: () => false
|
|
71
72
|
};
|
|
72
73
|
mockTerminalService = {
|
|
73
74
|
getByTerminalId: () => ({
|
|
@@ -87,6 +88,94 @@ describe('Workspace Task Provider Cancellation Tests', () => {
|
|
|
87
88
|
afterEach(() => {
|
|
88
89
|
cancellationTokenSource.dispose();
|
|
89
90
|
});
|
|
91
|
+
describe('Task cancellation with completed tasks', () => {
|
|
92
|
+
it('should NOT terminate task if task has already completed (not in runningTasks)', async () => {
|
|
93
|
+
let terminateTaskCalled = false;
|
|
94
|
+
mockTaskService.terminateTask = async () => {
|
|
95
|
+
terminateTaskCalled = true;
|
|
96
|
+
};
|
|
97
|
+
// Simulate task already completed (isTaskRunning returns false)
|
|
98
|
+
mockTaskService.isTaskRunning = () => false;
|
|
99
|
+
// Mock getTerminateSignal to never resolve (simulates in-flight handler)
|
|
100
|
+
mockTaskService.getTerminateSignal = () => new Promise(() => { });
|
|
101
|
+
const taskRunnerProvider = container.get(workspace_task_provider_1.TaskRunnerProvider);
|
|
102
|
+
const handler = taskRunnerProvider.getTool().handler;
|
|
103
|
+
// Start task execution (will hang on getTerminateSignal)
|
|
104
|
+
handler(JSON.stringify({ taskName: 'build' }), mockCtx);
|
|
105
|
+
// Give time for the handler to register the cancellation listener
|
|
106
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
107
|
+
// Cancel while handler is "in-flight"
|
|
108
|
+
cancellationTokenSource.cancel();
|
|
109
|
+
// Give time for cancellation to process
|
|
110
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
111
|
+
// terminateTask should NOT have been called since isTaskRunning returns false
|
|
112
|
+
(0, chai_1.expect)(terminateTaskCalled).to.be.false;
|
|
113
|
+
});
|
|
114
|
+
it('should terminate task if task is still running', async () => {
|
|
115
|
+
let terminateTaskCalled = false;
|
|
116
|
+
mockTaskService.terminateTask = async () => {
|
|
117
|
+
terminateTaskCalled = true;
|
|
118
|
+
};
|
|
119
|
+
// Mock isTaskRunning to return true (task still running)
|
|
120
|
+
mockTaskService.isTaskRunning = () => true;
|
|
121
|
+
// Mock getTerminateSignal to never resolve (simulates in-flight task)
|
|
122
|
+
mockTaskService.getTerminateSignal = () => new Promise(() => { });
|
|
123
|
+
const taskRunnerProvider = container.get(workspace_task_provider_1.TaskRunnerProvider);
|
|
124
|
+
const handler = taskRunnerProvider.getTool().handler;
|
|
125
|
+
// Start task execution (will hang on getTerminateSignal)
|
|
126
|
+
handler(JSON.stringify({ taskName: 'build' }), mockCtx);
|
|
127
|
+
// Give time for the handler to register the cancellation listener
|
|
128
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
129
|
+
// Cancel while task is "in-flight"
|
|
130
|
+
cancellationTokenSource.cancel();
|
|
131
|
+
// Give time for cancellation to process
|
|
132
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
133
|
+
// terminateTask SHOULD have been called since isTaskRunning returns true
|
|
134
|
+
(0, chai_1.expect)(terminateTaskCalled).to.be.true;
|
|
135
|
+
});
|
|
136
|
+
it('should handle multiple tasks with shared cancellation token - only terminate running tasks', async () => {
|
|
137
|
+
const terminatedTasks = [];
|
|
138
|
+
mockTaskService.terminateTask = async (taskInfo) => {
|
|
139
|
+
terminatedTasks.push(taskInfo.taskId);
|
|
140
|
+
};
|
|
141
|
+
// Mock isTaskRunning to simulate: task 0 completed, tasks 1 & 2 still running
|
|
142
|
+
mockTaskService.isTaskRunning = (taskId) => taskId !== 0;
|
|
143
|
+
// Mock getTerminateSignal to never resolve (simulates in-flight handlers)
|
|
144
|
+
mockTaskService.getTerminateSignal = () => new Promise(() => { });
|
|
145
|
+
// Mock runTaskByLabel to return different task IDs
|
|
146
|
+
let taskIdCounter = 0;
|
|
147
|
+
mockTaskService.runTaskByLabel = async (token, taskLabel) => ({
|
|
148
|
+
taskId: taskIdCounter++,
|
|
149
|
+
terminalId: taskIdCounter - 1,
|
|
150
|
+
config: {
|
|
151
|
+
label: taskLabel,
|
|
152
|
+
_scope: 'workspace',
|
|
153
|
+
type: 'shell'
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const taskRunnerProvider = container.get(workspace_task_provider_1.TaskRunnerProvider);
|
|
157
|
+
const handler = taskRunnerProvider.getTool().handler;
|
|
158
|
+
// Use ONE shared CancellationTokenSource (simulates real scenario)
|
|
159
|
+
const sharedCts = new core_1.CancellationTokenSource();
|
|
160
|
+
const sharedCtx = { cancellationToken: sharedCts.token };
|
|
161
|
+
// Call handler three times with the same shared cancellation token
|
|
162
|
+
handler(JSON.stringify({ taskName: 'build' }), sharedCtx);
|
|
163
|
+
handler(JSON.stringify({ taskName: 'test' }), sharedCtx);
|
|
164
|
+
handler(JSON.stringify({ taskName: 'lint' }), sharedCtx);
|
|
165
|
+
// Give time for handlers to register cancellation listeners
|
|
166
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
167
|
+
// Cancel the shared token once - this fires all registered listeners
|
|
168
|
+
sharedCts.cancel();
|
|
169
|
+
// Give time for cancellation listeners to fire
|
|
170
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
171
|
+
// Only task 1 and 2 should have been terminated (task 0 was completed)
|
|
172
|
+
(0, chai_1.expect)(terminatedTasks).to.have.lengthOf(2);
|
|
173
|
+
(0, chai_1.expect)(terminatedTasks).to.include(1);
|
|
174
|
+
(0, chai_1.expect)(terminatedTasks).to.include(2);
|
|
175
|
+
(0, chai_1.expect)(terminatedTasks).to.not.include(0);
|
|
176
|
+
sharedCts.dispose();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
90
179
|
it('TaskListProvider should respect cancellation token', async () => {
|
|
91
180
|
const taskListProvider = container.get(workspace_task_provider_1.TaskListProvider);
|
|
92
181
|
cancellationTokenSource.cancel();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-task-provider.spec.js","sourceRoot":"","sources":["../../src/browser/workspace-task-provider.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,+BAA8B;AAC9B,sCAAsD;AACtD,uEAAiF;AAEjF,4DAAyD;AACzD,uEAAmE;AACnE,wFAAoF;AAIpF,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACxD,IAAI,uBAAgD,CAAC;IACrD,IAAI,OAA8B,CAAC;IACnC,IAAI,SAAoB,CAAC;IACzB,IAAI,eAA4B,CAAC;IACjC,IAAI,mBAAoC,CAAC;IAEzC,UAAU,CAAC,GAAG,EAAE;QACZ,uBAAuB,GAAG,IAAI,8BAAuB,EAAE,CAAC;QAExD,qBAAqB;QACrB,OAAO,GAAG;YACN,iBAAiB,EAAE,uBAAuB,CAAC,KAAK;SACnD,CAAC;QAEF,uCAAuC;QACvC,SAAS,GAAG,IAAI,qBAAS,EAAE,CAAC;QAE5B,oBAAoB;QACpB,eAAe,GAAG;YACd,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG;YAC1B,QAAQ,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE,CAAC;gBAC/B;oBACI,KAAK,EAAE,OAAO;oBACd,MAAM,EAAE,WAAW;oBACnB,IAAI,EAAE,OAAO;iBACK;gBACtB;oBACI,KAAK,EAAE,MAAM;oBACb,MAAM,EAAE,WAAW;oBACnB,IAAI,EAAE,OAAO;iBACK;aACzB;YACD,cAAc,EAAE,KAAK,EAAE,KAAa,EAAE,SAAiB,EAAE,EAAE;gBACvD,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;oBAChD,OAAO;wBACH,MAAM,EAAE,CAAC;wBACT,UAAU,EAAE,CAAC;wBACb,MAAM,EAAE;4BACJ,KAAK,EAAE,SAAS;4BAChB,MAAM,EAAE,WAAW;4BACnB,IAAI,EAAE,OAAO;yBAChB;qBACQ,CAAC;gBAClB,CAAC;gBACD,OAAO,SAAS,CAAC;YACrB,CAAC;YACD,aAAa,EAAE,KAAK,EAAE,cAAwB,EAAE,EAAE;gBAC9C,oBAAoB;YACxB,CAAC;YACD,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"workspace-task-provider.spec.js","sourceRoot":"","sources":["../../src/browser/workspace-task-provider.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/ai-ide",
|
|
3
|
-
"version": "1.71.0-next.
|
|
3
|
+
"version": "1.71.0-next.19+ccda46cbe",
|
|
4
4
|
"description": "AI IDE Agents Extension",
|
|
5
5
|
"license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -15,24 +15,24 @@
|
|
|
15
15
|
"theia-extension"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@theia/ai-chat": "1.71.0-next.
|
|
19
|
-
"@theia/ai-chat-ui": "1.71.0-next.
|
|
20
|
-
"@theia/ai-core": "1.71.0-next.
|
|
21
|
-
"@theia/ai-mcp": "1.71.0-next.
|
|
22
|
-
"@theia/ai-terminal": "1.71.0-next.
|
|
23
|
-
"@theia/core": "1.71.0-next.
|
|
24
|
-
"@theia/debug": "1.71.0-next.
|
|
25
|
-
"@theia/editor": "1.71.0-next.
|
|
26
|
-
"@theia/filesystem": "1.71.0-next.
|
|
27
|
-
"@theia/markers": "1.71.0-next.
|
|
28
|
-
"@theia/monaco": "1.71.0-next.
|
|
29
|
-
"@theia/navigator": "1.71.0-next.
|
|
30
|
-
"@theia/preferences": "1.71.0-next.
|
|
31
|
-
"@theia/scm": "1.71.0-next.
|
|
32
|
-
"@theia/search-in-workspace": "1.71.0-next.
|
|
33
|
-
"@theia/task": "1.71.0-next.
|
|
34
|
-
"@theia/terminal": "1.71.0-next.
|
|
35
|
-
"@theia/workspace": "1.71.0-next.
|
|
18
|
+
"@theia/ai-chat": "1.71.0-next.19+ccda46cbe",
|
|
19
|
+
"@theia/ai-chat-ui": "1.71.0-next.19+ccda46cbe",
|
|
20
|
+
"@theia/ai-core": "1.71.0-next.19+ccda46cbe",
|
|
21
|
+
"@theia/ai-mcp": "1.71.0-next.19+ccda46cbe",
|
|
22
|
+
"@theia/ai-terminal": "1.71.0-next.19+ccda46cbe",
|
|
23
|
+
"@theia/core": "1.71.0-next.19+ccda46cbe",
|
|
24
|
+
"@theia/debug": "1.71.0-next.19+ccda46cbe",
|
|
25
|
+
"@theia/editor": "1.71.0-next.19+ccda46cbe",
|
|
26
|
+
"@theia/filesystem": "1.71.0-next.19+ccda46cbe",
|
|
27
|
+
"@theia/markers": "1.71.0-next.19+ccda46cbe",
|
|
28
|
+
"@theia/monaco": "1.71.0-next.19+ccda46cbe",
|
|
29
|
+
"@theia/navigator": "1.71.0-next.19+ccda46cbe",
|
|
30
|
+
"@theia/preferences": "1.71.0-next.19+ccda46cbe",
|
|
31
|
+
"@theia/scm": "1.71.0-next.19+ccda46cbe",
|
|
32
|
+
"@theia/search-in-workspace": "1.71.0-next.19+ccda46cbe",
|
|
33
|
+
"@theia/task": "1.71.0-next.19+ccda46cbe",
|
|
34
|
+
"@theia/terminal": "1.71.0-next.19+ccda46cbe",
|
|
35
|
+
"@theia/workspace": "1.71.0-next.19+ccda46cbe",
|
|
36
36
|
"date-fns": "^4.1.0",
|
|
37
37
|
"ignore": "^6.0.0",
|
|
38
38
|
"js-yaml": "^4.1.0",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@theia/cli": "1.71.0-next.
|
|
48
|
-
"@theia/test": "1.71.0-next.
|
|
47
|
+
"@theia/cli": "1.71.0-next.19+ccda46cbe",
|
|
48
|
+
"@theia/test": "1.71.0-next.19+ccda46cbe"
|
|
49
49
|
},
|
|
50
50
|
"theiaExtensions": [
|
|
51
51
|
{
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"nyc": {
|
|
70
70
|
"extends": "../../configs/nyc.json"
|
|
71
71
|
},
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "ccda46cbecbb8184f5b7bd56102472beaf8c2408"
|
|
73
73
|
}
|
|
@@ -74,7 +74,8 @@ describe('Workspace Task Provider Cancellation Tests', () => {
|
|
|
74
74
|
terminateTask: async (activeTaskInfo: TaskInfo) => {
|
|
75
75
|
// Track termination
|
|
76
76
|
},
|
|
77
|
-
getTerminateSignal: async () => 'SIGTERM'
|
|
77
|
+
getTerminateSignal: async () => 'SIGTERM',
|
|
78
|
+
isTaskRunning: () => false
|
|
78
79
|
} as unknown as TaskService;
|
|
79
80
|
|
|
80
81
|
mockTerminalService = {
|
|
@@ -98,6 +99,123 @@ describe('Workspace Task Provider Cancellation Tests', () => {
|
|
|
98
99
|
cancellationTokenSource.dispose();
|
|
99
100
|
});
|
|
100
101
|
|
|
102
|
+
describe('Task cancellation with completed tasks', () => {
|
|
103
|
+
it('should NOT terminate task if task has already completed (not in runningTasks)', async () => {
|
|
104
|
+
let terminateTaskCalled = false;
|
|
105
|
+
mockTaskService.terminateTask = async () => {
|
|
106
|
+
terminateTaskCalled = true;
|
|
107
|
+
};
|
|
108
|
+
// Simulate task already completed (isTaskRunning returns false)
|
|
109
|
+
mockTaskService.isTaskRunning = () => false;
|
|
110
|
+
|
|
111
|
+
// Mock getTerminateSignal to never resolve (simulates in-flight handler)
|
|
112
|
+
mockTaskService.getTerminateSignal = () => new Promise(() => { });
|
|
113
|
+
|
|
114
|
+
const taskRunnerProvider = container.get(TaskRunnerProvider);
|
|
115
|
+
const handler = taskRunnerProvider.getTool().handler;
|
|
116
|
+
|
|
117
|
+
// Start task execution (will hang on getTerminateSignal)
|
|
118
|
+
handler(JSON.stringify({ taskName: 'build' }), mockCtx);
|
|
119
|
+
|
|
120
|
+
// Give time for the handler to register the cancellation listener
|
|
121
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
122
|
+
|
|
123
|
+
// Cancel while handler is "in-flight"
|
|
124
|
+
cancellationTokenSource.cancel();
|
|
125
|
+
|
|
126
|
+
// Give time for cancellation to process
|
|
127
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
128
|
+
|
|
129
|
+
// terminateTask should NOT have been called since isTaskRunning returns false
|
|
130
|
+
expect(terminateTaskCalled).to.be.false;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should terminate task if task is still running', async () => {
|
|
134
|
+
let terminateTaskCalled = false;
|
|
135
|
+
mockTaskService.terminateTask = async () => {
|
|
136
|
+
terminateTaskCalled = true;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Mock isTaskRunning to return true (task still running)
|
|
140
|
+
mockTaskService.isTaskRunning = () => true;
|
|
141
|
+
|
|
142
|
+
// Mock getTerminateSignal to never resolve (simulates in-flight task)
|
|
143
|
+
mockTaskService.getTerminateSignal = () => new Promise(() => { });
|
|
144
|
+
|
|
145
|
+
const taskRunnerProvider = container.get(TaskRunnerProvider);
|
|
146
|
+
const handler = taskRunnerProvider.getTool().handler;
|
|
147
|
+
|
|
148
|
+
// Start task execution (will hang on getTerminateSignal)
|
|
149
|
+
handler(JSON.stringify({ taskName: 'build' }), mockCtx);
|
|
150
|
+
|
|
151
|
+
// Give time for the handler to register the cancellation listener
|
|
152
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
153
|
+
|
|
154
|
+
// Cancel while task is "in-flight"
|
|
155
|
+
cancellationTokenSource.cancel();
|
|
156
|
+
|
|
157
|
+
// Give time for cancellation to process
|
|
158
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
159
|
+
|
|
160
|
+
// terminateTask SHOULD have been called since isTaskRunning returns true
|
|
161
|
+
expect(terminateTaskCalled).to.be.true;
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should handle multiple tasks with shared cancellation token - only terminate running tasks', async () => {
|
|
165
|
+
const terminatedTasks: number[] = [];
|
|
166
|
+
mockTaskService.terminateTask = async (taskInfo: TaskInfo) => {
|
|
167
|
+
terminatedTasks.push(taskInfo.taskId);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Mock isTaskRunning to simulate: task 0 completed, tasks 1 & 2 still running
|
|
171
|
+
mockTaskService.isTaskRunning = (taskId: number) => taskId !== 0;
|
|
172
|
+
|
|
173
|
+
// Mock getTerminateSignal to never resolve (simulates in-flight handlers)
|
|
174
|
+
mockTaskService.getTerminateSignal = () => new Promise(() => { });
|
|
175
|
+
|
|
176
|
+
// Mock runTaskByLabel to return different task IDs
|
|
177
|
+
let taskIdCounter = 0;
|
|
178
|
+
mockTaskService.runTaskByLabel = async (token: number, taskLabel: string) => ({
|
|
179
|
+
taskId: taskIdCounter++,
|
|
180
|
+
terminalId: taskIdCounter - 1,
|
|
181
|
+
config: {
|
|
182
|
+
label: taskLabel,
|
|
183
|
+
_scope: 'workspace',
|
|
184
|
+
type: 'shell'
|
|
185
|
+
}
|
|
186
|
+
} as TaskInfo);
|
|
187
|
+
|
|
188
|
+
const taskRunnerProvider = container.get(TaskRunnerProvider);
|
|
189
|
+
const handler = taskRunnerProvider.getTool().handler;
|
|
190
|
+
|
|
191
|
+
// Use ONE shared CancellationTokenSource (simulates real scenario)
|
|
192
|
+
const sharedCts = new CancellationTokenSource();
|
|
193
|
+
const sharedCtx: ToolInvocationContext = { cancellationToken: sharedCts.token };
|
|
194
|
+
|
|
195
|
+
// Call handler three times with the same shared cancellation token
|
|
196
|
+
handler(JSON.stringify({ taskName: 'build' }), sharedCtx);
|
|
197
|
+
handler(JSON.stringify({ taskName: 'test' }), sharedCtx);
|
|
198
|
+
handler(JSON.stringify({ taskName: 'lint' }), sharedCtx);
|
|
199
|
+
|
|
200
|
+
// Give time for handlers to register cancellation listeners
|
|
201
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
202
|
+
|
|
203
|
+
// Cancel the shared token once - this fires all registered listeners
|
|
204
|
+
sharedCts.cancel();
|
|
205
|
+
|
|
206
|
+
// Give time for cancellation listeners to fire
|
|
207
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
208
|
+
|
|
209
|
+
// Only task 1 and 2 should have been terminated (task 0 was completed)
|
|
210
|
+
expect(terminatedTasks).to.have.lengthOf(2);
|
|
211
|
+
expect(terminatedTasks).to.include(1);
|
|
212
|
+
expect(terminatedTasks).to.include(2);
|
|
213
|
+
expect(terminatedTasks).to.not.include(0);
|
|
214
|
+
|
|
215
|
+
sharedCts.dispose();
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
101
219
|
it('TaskListProvider should respect cancellation token', async () => {
|
|
102
220
|
const taskListProvider = container.get(TaskListProvider);
|
|
103
221
|
cancellationTokenSource.cancel();
|
|
@@ -113,7 +113,10 @@ export class TaskRunnerProvider implements ToolProvider {
|
|
|
113
113
|
return `Did not find a task for the label: '${args.taskName}'`;
|
|
114
114
|
}
|
|
115
115
|
cancellationToken?.onCancellationRequested(() => {
|
|
116
|
-
|
|
116
|
+
// Only terminate if the task is still running
|
|
117
|
+
if (this.taskService.isTaskRunning(taskInfo.taskId)) {
|
|
118
|
+
this.taskService.terminateTask(taskInfo);
|
|
119
|
+
}
|
|
117
120
|
});
|
|
118
121
|
if (cancellationToken?.isCancellationRequested) {
|
|
119
122
|
return JSON.stringify({ error: 'Operation cancelled by user' });
|