Skip to content

Commit fed69ad

Browse files
committed
debug session: use queue to make sure output messages get processed in correct order
fixes microsoft#91416
1 parent 622ddc0 commit fed69ad

File tree

1 file changed

+44
-48
lines changed

1 file changed

+44
-48
lines changed

src/vs/workbench/contrib/debug/browser/debugSession.ts

+44-48
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { RawDebugSession } from 'vs/workbench/contrib/debug/browser/rawDebugSess
1919
import { IProductService } from 'vs/platform/product/common/productService';
2020
import { IWorkspaceFolder, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
2121
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
22-
import { RunOnceScheduler } from 'vs/base/common/async';
22+
import { RunOnceScheduler, Queue } from 'vs/base/common/async';
2323
import { generateUuid } from 'vs/base/common/uuid';
2424
import { IHostService } from 'vs/workbench/services/host/browser/host';
2525
import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
@@ -807,62 +807,58 @@ export class DebugSession implements IDebugSession {
807807
this._onDidChangeState.fire();
808808
}));
809809

810-
let outpuPromises: Promise<void>[] = [];
810+
const outputQueue = new Queue<void>();
811811
this.rawListeners.push(this.raw.onDidOutput(async event => {
812-
if (!event.body || !this.raw) {
813-
return;
814-
}
815-
816-
const outputSeverity = event.body.category === 'stderr' ? severity.Error : event.body.category === 'console' ? severity.Warning : severity.Info;
817-
if (event.body.category === 'telemetry') {
818-
// only log telemetry events from debug adapter if the debug extension provided the telemetry key
819-
// and the user opted in telemetry
820-
if (this.raw.customTelemetryService && this.telemetryService.isOptedIn) {
821-
// __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly.
822-
this.raw.customTelemetryService.publicLog(event.body.output, event.body.data);
812+
outputQueue.queue(async () => {
813+
if (!event.body || !this.raw) {
814+
return;
823815
}
824816

825-
return;
826-
}
817+
const outputSeverity = event.body.category === 'stderr' ? severity.Error : event.body.category === 'console' ? severity.Warning : severity.Info;
818+
if (event.body.category === 'telemetry') {
819+
// only log telemetry events from debug adapter if the debug extension provided the telemetry key
820+
// and the user opted in telemetry
821+
if (this.raw.customTelemetryService && this.telemetryService.isOptedIn) {
822+
// __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly.
823+
this.raw.customTelemetryService.publicLog(event.body.output, event.body.data);
824+
}
827825

828-
// Make sure to append output in the correct order by properly waiting on preivous promises #33822
829-
const waitFor = outpuPromises.slice();
830-
const source = event.body.source && event.body.line ? {
831-
lineNumber: event.body.line,
832-
column: event.body.column ? event.body.column : 1,
833-
source: this.getSource(event.body.source)
834-
} : undefined;
826+
return;
827+
}
835828

836-
if (event.body.group === 'start' || event.body.group === 'startCollapsed') {
837-
const expanded = event.body.group === 'start';
838-
this.repl.startGroup(event.body.output || '', expanded, source);
839-
return;
840-
}
841-
if (event.body.group === 'end') {
842-
this.repl.endGroup();
843-
if (!event.body.output) {
844-
// Only return if the end event does not have additional output in it
829+
// Make sure to append output in the correct order by properly waiting on preivous promises #33822
830+
const source = event.body.source && event.body.line ? {
831+
lineNumber: event.body.line,
832+
column: event.body.column ? event.body.column : 1,
833+
source: this.getSource(event.body.source)
834+
} : undefined;
835+
836+
if (event.body.group === 'start' || event.body.group === 'startCollapsed') {
837+
const expanded = event.body.group === 'start';
838+
this.repl.startGroup(event.body.output || '', expanded, source);
845839
return;
846840
}
847-
}
841+
if (event.body.group === 'end') {
842+
this.repl.endGroup();
843+
if (!event.body.output) {
844+
// Only return if the end event does not have additional output in it
845+
return;
846+
}
847+
}
848848

849-
if (event.body.variablesReference) {
850-
const container = new ExpressionContainer(this, undefined, event.body.variablesReference, generateUuid());
851-
outpuPromises.push(container.getChildren().then(async children => {
852-
await Promise.all(waitFor);
853-
children.forEach(child => {
854-
// Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names)
855-
(<any>child).name = null;
856-
this.appendToRepl(child, outputSeverity, source);
849+
if (event.body.variablesReference) {
850+
const container = new ExpressionContainer(this, undefined, event.body.variablesReference, generateUuid());
851+
await container.getChildren().then(children => {
852+
children.forEach(child => {
853+
// Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names)
854+
(<any>child).name = null;
855+
this.appendToRepl(child, outputSeverity, source);
856+
});
857857
});
858-
}));
859-
} else if (typeof event.body.output === 'string') {
860-
await Promise.all(waitFor);
861-
this.appendToRepl(event.body.output, outputSeverity, source);
862-
}
863-
864-
await Promise.all(outpuPromises);
865-
outpuPromises = [];
858+
} else if (typeof event.body.output === 'string') {
859+
this.appendToRepl(event.body.output, outputSeverity, source);
860+
}
861+
});
866862
}));
867863

868864
this.rawListeners.push(this.raw.onDidBreakpoint(event => {

0 commit comments

Comments
 (0)