* Terminate a background process
(
processId: string
)
| 1273 | * Terminate a background process |
| 1274 | */ |
| 1275 | async terminate( |
| 1276 | processId: string |
| 1277 | ): Promise<{ success: true } | { success: false; error: string }> { |
| 1278 | log.debug(`BackgroundProcessManager.terminate(${processId}) called`); |
| 1279 | |
| 1280 | // Get process from Map |
| 1281 | const proc = this.processes.get(processId); |
| 1282 | if (!proc) { |
| 1283 | return { success: false, error: `Process not found: ${processId}` }; |
| 1284 | } |
| 1285 | |
| 1286 | // If already terminated, return success (idempotent) after clearing any pending monitor flush. |
| 1287 | if (proc.status === "exited" || proc.status === "killed" || proc.status === "failed") { |
| 1288 | this.stopMonitor(proc, false); |
| 1289 | log.debug(`Process ${processId} already terminated with status: ${proc.status}`); |
| 1290 | return { success: true }; |
| 1291 | } |
| 1292 | |
| 1293 | try { |
| 1294 | this.stopMonitor(proc, true); |
| 1295 | |
| 1296 | await proc.handle.terminate(); |
| 1297 | |
| 1298 | // Update process status and exit code |
| 1299 | proc.status = "killed"; |
| 1300 | proc.exitCode = (await proc.handle.getExitCode()) ?? undefined; |
| 1301 | proc.exitTime ??= Date.now(); |
| 1302 | |
| 1303 | // Update meta.json |
| 1304 | await this.updateMetaFile(proc).catch((err: unknown) => { |
| 1305 | log.debug(`BackgroundProcessManager: Failed to update meta.json: ${getErrorMessage(err)}`); |
| 1306 | }); |
| 1307 | |
| 1308 | // Dispose of the handle |
| 1309 | await proc.handle.dispose(); |
| 1310 | |
| 1311 | log.debug(`Process ${processId} terminated successfully`); |
| 1312 | this.emitChange(proc.workspaceId); |
| 1313 | return { success: true }; |
| 1314 | } catch (error) { |
| 1315 | const errorMessage = getErrorMessage(error); |
| 1316 | log.debug(`Error terminating process ${processId}: ${errorMessage}`); |
| 1317 | // Mark as killed even if there was an error (process likely already dead) |
| 1318 | proc.status = "killed"; |
| 1319 | proc.exitTime ??= Date.now(); |
| 1320 | // Update meta.json |
| 1321 | await this.updateMetaFile(proc).catch((err: unknown) => { |
| 1322 | log.debug(`BackgroundProcessManager: Failed to update meta.json: ${getErrorMessage(err)}`); |
| 1323 | }); |
| 1324 | // Ensure handle is cleaned up even on error |
| 1325 | await proc.handle.dispose(); |
| 1326 | this.emitChange(proc.workspaceId); |
| 1327 | return { success: true }; |
| 1328 | } |
| 1329 | } |
| 1330 | |
| 1331 | /** |
| 1332 | * Terminate all background processes across all workspaces. |
no test coverage detected