Skip to content

Commit

Permalink
Rework waitForOutputEvent to not miss events
Browse files Browse the repository at this point in the history
The code used to do this.once('output') in a tight loop,
but this meant that between processing one of the iterations
and the next iteration of the loop a message may have
been output. Instead use this.on('output') so all messages
are processed.

Prerequiste for eclipse-cdt-cloud#239 which generates multiple events quickly
  • Loading branch information
jonahgraham committed Feb 1, 2023
1 parent f148157 commit 15c7ba0
Showing 1 changed file with 27 additions and 21 deletions.
48 changes: 27 additions & 21 deletions src/integration-tests/debugClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,13 @@ export class CdtDebugClient extends DebugClient {
}

/*
* Returns a promise that will resolve if an output event with a specific category was received.
* Returns a promise that will resolve if an output event
* with a specific category and optional output message was received.
* The promise will be rejected if a timeout occurs.
*/
public async waitForOutputEvent(
category: string,
output?: string,
timeout: number = this.defaultTimeout
): Promise<DebugProtocol.OutputEvent> {
const isOutputEvent = (
Expand All @@ -249,26 +251,30 @@ export class CdtDebugClient extends DebugClient {
);
};

const timer = setTimeout(() => {
throw new Error(
`no output event with category '${category}' received after ${timeout} ms`
);
}, timeout);

for (;;) {
const event = await new Promise((resolve) =>
this.once('output', (e) => resolve(e))
);

if (!isOutputEvent(event)) {
continue;
}

if (event.body.category === category) {
clearTimeout(timer);
return event;
}
}
return new Promise<DebugProtocol.OutputEvent>((resolve, reject) => {
const outputProcessor = (event: DebugProtocol.OutputEvent) => {
if (isOutputEvent(event) && event.body.category === category) {
if (output === undefined || output === event.body.output) {
clearTimeout(timer);
this.off('output', outputProcessor);
resolve(event);
}
}
};
const timer = setTimeout(() => {
this.off('output', outputProcessor);
reject(
new Error(
`no output event with category '${category}' ${
output === undefined
? ''
: `and output message '${output}'`
} received after ${timeout} ms`
)
);
}, timeout);
this.on('output', outputProcessor);
});
}

/**
Expand Down

0 comments on commit 15c7ba0

Please sign in to comment.