Skip to content

Commit

Permalink
debug session: use queue to make sure output messages get processed i…
Browse files Browse the repository at this point in the history
…n correct order

fixes microsoft#91416
  • Loading branch information
isidorn committed Feb 26, 2020
1 parent 622ddc0 commit fed69ad
Showing 1 changed file with 44 additions and 48 deletions.
92 changes: 44 additions & 48 deletions src/vs/workbench/contrib/debug/browser/debugSession.ts
Expand Up @@ -19,7 +19,7 @@ import { RawDebugSession } from 'vs/workbench/contrib/debug/browser/rawDebugSess
import { IProductService } from 'vs/platform/product/common/productService';
import { IWorkspaceFolder, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { RunOnceScheduler, Queue } from 'vs/base/common/async';
import { generateUuid } from 'vs/base/common/uuid';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
Expand Down Expand Up @@ -807,62 +807,58 @@ export class DebugSession implements IDebugSession {
this._onDidChangeState.fire();
}));

let outpuPromises: Promise<void>[] = [];
const outputQueue = new Queue<void>();
this.rawListeners.push(this.raw.onDidOutput(async event => {
if (!event.body || !this.raw) {
return;
}

const outputSeverity = event.body.category === 'stderr' ? severity.Error : event.body.category === 'console' ? severity.Warning : severity.Info;
if (event.body.category === 'telemetry') {
// only log telemetry events from debug adapter if the debug extension provided the telemetry key
// and the user opted in telemetry
if (this.raw.customTelemetryService && this.telemetryService.isOptedIn) {
// __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly.
this.raw.customTelemetryService.publicLog(event.body.output, event.body.data);
outputQueue.queue(async () => {
if (!event.body || !this.raw) {
return;
}

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

// Make sure to append output in the correct order by properly waiting on preivous promises #33822
const waitFor = outpuPromises.slice();
const source = event.body.source && event.body.line ? {
lineNumber: event.body.line,
column: event.body.column ? event.body.column : 1,
source: this.getSource(event.body.source)
} : undefined;
return;
}

if (event.body.group === 'start' || event.body.group === 'startCollapsed') {
const expanded = event.body.group === 'start';
this.repl.startGroup(event.body.output || '', expanded, source);
return;
}
if (event.body.group === 'end') {
this.repl.endGroup();
if (!event.body.output) {
// Only return if the end event does not have additional output in it
// Make sure to append output in the correct order by properly waiting on preivous promises #33822
const source = event.body.source && event.body.line ? {
lineNumber: event.body.line,
column: event.body.column ? event.body.column : 1,
source: this.getSource(event.body.source)
} : undefined;

if (event.body.group === 'start' || event.body.group === 'startCollapsed') {
const expanded = event.body.group === 'start';
this.repl.startGroup(event.body.output || '', expanded, source);
return;
}
}
if (event.body.group === 'end') {
this.repl.endGroup();
if (!event.body.output) {
// Only return if the end event does not have additional output in it
return;
}
}

if (event.body.variablesReference) {
const container = new ExpressionContainer(this, undefined, event.body.variablesReference, generateUuid());
outpuPromises.push(container.getChildren().then(async children => {
await Promise.all(waitFor);
children.forEach(child => {
// Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names)
(<any>child).name = null;
this.appendToRepl(child, outputSeverity, source);
if (event.body.variablesReference) {
const container = new ExpressionContainer(this, undefined, event.body.variablesReference, generateUuid());
await container.getChildren().then(children => {
children.forEach(child => {
// Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names)
(<any>child).name = null;
this.appendToRepl(child, outputSeverity, source);
});
});
}));
} else if (typeof event.body.output === 'string') {
await Promise.all(waitFor);
this.appendToRepl(event.body.output, outputSeverity, source);
}

await Promise.all(outpuPromises);
outpuPromises = [];
} else if (typeof event.body.output === 'string') {
this.appendToRepl(event.body.output, outputSeverity, source);
}
});
}));

this.rawListeners.push(this.raw.onDidBreakpoint(event => {
Expand Down

0 comments on commit fed69ad

Please sign in to comment.