Skip to content

Commit f1d646f

Browse files
author
Akos Kitta
committed
feat: wait for monitor resource cleanup
Wait for the cancel error from the CLI when requesting connection close. Signed-off-by: Akos Kitta <[email protected]>
1 parent 9c36fe1 commit f1d646f

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

arduino-ide-extension/src/node/monitor-service.ts

+30-15
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ export class MonitorService extends CoreClientAware implements Disposable {
410410
]) as Promise<unknown> as Promise<void>;
411411
}
412412

413+
private closingDuplex: Promise<void> | undefined;
414+
413415
/**
414416
* Pauses the currently running monitor, it still closes the gRPC connection
415417
* with the underlying monitor process but it doesn't stop the message handlers
@@ -419,28 +421,41 @@ export class MonitorService extends CoreClientAware implements Disposable {
419421
* @returns
420422
*/
421423
async pause(): Promise<void> {
422-
return new Promise(async (resolve) => {
423-
if (!this.duplex) {
424-
this.logger.warn(
425-
`monitor to ${this.port?.address} using ${this.port?.protocol} already stopped`
426-
);
427-
return resolve();
428-
}
429-
await new Promise<void>((closeResolve) => {
430-
if (!this.duplex) {
431-
return closeResolve();
432-
}
433-
this.duplex.write(new MonitorRequest().setClose(true), closeResolve);
434-
});
435-
this.duplex.on('end', resolve);
424+
const duplex = this.duplex;
425+
if (!duplex) {
426+
this.logger.warn(
427+
`monitor to ${this.port?.address} using ${this.port?.protocol} already stopped`
428+
);
429+
return;
430+
}
431+
if (this.closingDuplex) {
432+
return this.closingDuplex;
433+
}
434+
const deferredClose = new Deferred<void>();
435+
this.closingDuplex = deferredClose.promise;
436+
437+
// to terminate the monitor connection, send a close request, and wait for the expected cancellation error
438+
duplex.once('error', (error) => {
439+
// TODO: check if cancel error
440+
deferredClose.resolve();
436441
});
442+
duplex.write(new MonitorRequest().setClose(true));
443+
try {
444+
await this.closingDuplex;
445+
} finally {
446+
this.closingDuplex = undefined;
447+
}
448+
// Sanity check
449+
if (!duplex.closed) {
450+
throw new Error('Could not close monitor connection');
451+
}
437452
}
438453

439454
/**
440455
* Stop the monitor currently running
441456
*/
442457
async stop(): Promise<void> {
443-
return this.pause().finally(this.stopMessagesHandlers.bind(this));
458+
return this.pause().finally(() => this.stopMessagesHandlers());
444459
}
445460

446461
/**

0 commit comments

Comments
 (0)