@@ -63,6 +63,8 @@ interface IActiveTerminalData {
63
63
state ?: TaskEventKind ;
64
64
}
65
65
66
+ const ReconnectionType = 'Task' ;
67
+
66
68
class InstanceManager {
67
69
private _currentInstances : number = 0 ;
68
70
private _counter : number = 0 ;
@@ -255,6 +257,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
255
257
this . _logService . trace ( `Could not reconnect to terminal ${ terminal . instanceId } with process details ${ terminal . shellLaunchConfig . attachPersistentProcess } ` ) ;
256
258
}
257
259
}
260
+ this . _hasReconnected = true ;
258
261
}
259
262
260
263
public get onDidStateChange ( ) : Event < ITaskEvent > {
@@ -270,10 +273,13 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
270
273
}
271
274
272
275
public reconnect ( task : Task , resolver : ITaskResolver , trigger : string = Triggers . command ) : ITaskExecuteResult | undefined {
273
- const terminals = this . _terminalService . getReconnectedTerminals ( 'Task' ) ;
276
+ const terminals = this . _terminalService . getReconnectedTerminals ( ReconnectionType ) ;
277
+ if ( ! terminals || terminals ?. length === 0 ) {
278
+ return ;
279
+ }
274
280
if ( ! this . _hasReconnected && terminals && terminals . length > 0 ) {
281
+ this . _reviveTerminals ( ) ;
275
282
this . _reconnectToTerminals ( terminals ) ;
276
- this . _hasReconnected = true ;
277
283
}
278
284
if ( this . _tasksToReconnect . includes ( task . _id ) ) {
279
285
this . _lastTask = new VerifiedTask ( task , resolver , trigger ) ;
@@ -449,12 +455,14 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
449
455
}
450
456
}
451
457
452
- private _removeFromActiveTasks ( task : Task ) : void {
453
- if ( ! this . _activeTasks [ task . getMapKey ( ) ] ) {
458
+ private _removeFromActiveTasks ( task : Task | string ) : void {
459
+ const key = typeof task === 'string' ? task : task . getMapKey ( ) ;
460
+ if ( ! this . _activeTasks [ key ] ) {
454
461
return ;
455
462
}
456
- delete this . _activeTasks [ task . getMapKey ( ) ] ;
457
- this . _removeInstances ( task ) ;
463
+ const taskToRemove = this . _activeTasks [ key ] ;
464
+ delete this . _activeTasks [ key ] ;
465
+ this . _removeInstances ( taskToRemove . task ) ;
458
466
}
459
467
460
468
private _fireTaskEvent ( event : ITaskEvent ) {
@@ -1059,7 +1067,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1059
1067
const isShellCommand = task . command . runtime === RuntimeType . Shell ;
1060
1068
const needsFolderQualification = this . _contextService . getWorkbenchState ( ) === WorkbenchState . WORKSPACE ;
1061
1069
const terminalName = this . _createTerminalName ( task ) ;
1062
- const type = 'Task' ;
1070
+ const type = ReconnectionType ;
1063
1071
const originalCommand = task . command . name ;
1064
1072
if ( isShellCommand ) {
1065
1073
let os : Platform . OperatingSystem ;
@@ -1289,17 +1297,40 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1289
1297
}
1290
1298
1291
1299
private _reviveTerminals ( ) : void {
1292
- if ( Object . entries ( this . _terminals ) . length === 0 ) {
1293
- for ( const terminal of this . _terminalService . instances ) {
1294
- if ( terminal . shellLaunchConfig . attachPersistentProcess ?. task ?. lastTask ) {
1295
- this . _terminals [ terminal . instanceId ] = { lastTask : terminal . shellLaunchConfig . attachPersistentProcess . task . lastTask , group : terminal . shellLaunchConfig . attachPersistentProcess . task . group , terminal } ;
1296
- }
1300
+ if ( Object . entries ( this . _terminals ) . length > 0 ) {
1301
+ return ;
1302
+ }
1303
+ const terminals = this . _terminalService . getReconnectedTerminals ( ReconnectionType ) ?. filter ( t => ! t . isDisposed ) ;
1304
+ if ( ! terminals ?. length ) {
1305
+ return ;
1306
+ }
1307
+ for ( const terminal of terminals ) {
1308
+ const task = terminal . shellLaunchConfig . attachPersistentProcess ?. task ;
1309
+ if ( ! task ) {
1310
+ continue ;
1297
1311
}
1312
+ const terminalData = { lastTask : task . lastTask , group : task . group , terminal } ;
1313
+ this . _terminals [ terminal . instanceId ] = terminalData ;
1314
+ terminal . onDisposed ( ( ) => this . _deleteTaskAndTerminal ( terminal , terminalData ) ) ;
1315
+ }
1316
+ }
1317
+
1318
+ private _deleteTaskAndTerminal ( terminal : ITerminalInstance , terminalData : ITerminalData ) : void {
1319
+ delete this . _terminals [ terminal . instanceId ] ;
1320
+ delete this . _sameTaskTerminals [ terminalData . lastTask ] ;
1321
+ this . _idleTaskTerminals . delete ( terminalData . lastTask ) ;
1322
+ // Delete the task now as a work around for cases when the onExit isn't fired.
1323
+ // This can happen if the terminal wasn't shutdown with an "immediate" flag and is expected.
1324
+ // For correct terminal re-use, the task needs to be deleted immediately.
1325
+ // Note that this shouldn't be a problem anymore since user initiated terminal kills are now immediate.
1326
+ const mapKey = terminalData . lastTask ;
1327
+ this . _removeFromActiveTasks ( mapKey ) ;
1328
+ if ( this . _busyTasks [ mapKey ] ) {
1329
+ delete this . _busyTasks [ mapKey ] ;
1298
1330
}
1299
1331
}
1300
1332
1301
1333
private async _createTerminal ( task : CustomTask | ContributedTask , resolver : VariableResolver , workspaceFolder : IWorkspaceFolder | undefined ) : Promise < [ ITerminalInstance | undefined , TaskError | undefined ] > {
1302
- this . _reviveTerminals ( ) ;
1303
1334
const platform = resolver . taskSystemInfo ? resolver . taskSystemInfo . platform : Platform . platform ;
1304
1335
const options = await this . _resolveOptions ( resolver , task . command . options ) ;
1305
1336
const presentationOptions = task . command . presentation ;
@@ -1398,29 +1429,14 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1398
1429
}
1399
1430
1400
1431
this . _terminalCreationQueue = this . _terminalCreationQueue . then ( ( ) => this . _doCreateTerminal ( group , launchConfigs ! ) ) ;
1401
- const result : ITerminalInstance = ( await this . _terminalCreationQueue ) ! ;
1402
- result . shellLaunchConfig . task = { lastTask : taskKey , group, label : task . _label , id : task . _id } ;
1403
- result . shellLaunchConfig . reconnectionOwner = 'Task' ;
1404
- const terminalKey = result . instanceId . toString ( ) ;
1405
- result . onDisposed ( ( ) => {
1406
- const terminalData = this . _terminals [ terminalKey ] ;
1407
- if ( terminalData ) {
1408
- delete this . _terminals [ terminalKey ] ;
1409
- delete this . _sameTaskTerminals [ terminalData . lastTask ] ;
1410
- this . _idleTaskTerminals . delete ( terminalData . lastTask ) ;
1411
- // Delete the task now as a work around for cases when the onExit isn't fired.
1412
- // This can happen if the terminal wasn't shutdown with an "immediate" flag and is expected.
1413
- // For correct terminal re-use, the task needs to be deleted immediately.
1414
- // Note that this shouldn't be a problem anymore since user initiated terminal kills are now immediate.
1415
- const mapKey = task . getMapKey ( ) ;
1416
- this . _removeFromActiveTasks ( task ) ;
1417
- if ( this . _busyTasks [ mapKey ] ) {
1418
- delete this . _busyTasks [ mapKey ] ;
1419
- }
1420
- }
1421
- } ) ;
1422
- this . _terminals [ terminalKey ] = { terminal : result , lastTask : taskKey , group } ;
1423
- return [ result , undefined ] ;
1432
+ const terminal : ITerminalInstance = ( await this . _terminalCreationQueue ) ! ;
1433
+ terminal . shellLaunchConfig . task = { lastTask : taskKey , group, label : task . _label , id : task . _id } ;
1434
+ terminal . shellLaunchConfig . reconnectionOwner = ReconnectionType ;
1435
+ const terminalKey = terminal . instanceId . toString ( ) ;
1436
+ const terminalData = { terminal : terminal , lastTask : taskKey , group } ;
1437
+ terminal . onDisposed ( ( ) => this . _deleteTaskAndTerminal ( terminal , terminalData ) ) ;
1438
+ this . _terminals [ terminalKey ] = terminalData ;
1439
+ return [ terminal , undefined ] ;
1424
1440
}
1425
1441
1426
1442
private _buildShellCommandLine ( platform : Platform . Platform , shellExecutable : string , shellOptions : IShellConfiguration | undefined , command : CommandString , originalCommand : CommandString | undefined , args : CommandString [ ] ) : string {
0 commit comments