Skip to content

Commit

Permalink
Review comments no. 2
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew committed Feb 14, 2024
1 parent 50d606f commit 194ec01
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 27 deletions.
28 changes: 12 additions & 16 deletions packages/langium/src/parser/async-parser.ts
Expand Up @@ -82,29 +82,28 @@ export abstract class AbstractThreadedAsyncParser implements AsyncParser {
async parse<T extends AstNode>(text: string, cancelToken: CancellationToken): Promise<ParseResult<T>> {
const worker = await this.acquireParserWorker(cancelToken);
const deferred = new Deferred<ParseResult<T>>();
let timeout: NodeJS.Timeout | undefined;
// If the cancellation token is requested, we wait for a certain time before terminating the worker.
// Since the cancellation token lives longer than the parsing process, we need to dispose the event listener.
// Otherwise, we might accidentally terminate the worker after the parsing process has finished.
const cancellation = cancelToken.onCancellationRequested(() => {
const timeout = setTimeout(() => {
this.killWorker(worker);
timeout = setTimeout(() => {
this.terminateWorker(worker);
}, this.terminationDelay);
deferred.finally(() => clearTimeout(timeout));
});
deferred.finally(() => {
try {
cancellation.dispose();
} catch (error) {
console.error(error);
}
});
worker.parse(text).then(result => {
result.value = this.hydrator.hydrate(result.value);
deferred.resolve(result as ParseResult<T>);
}).catch(err => {
deferred.reject(err);
}).finally(() => {
cancellation.dispose();
clearTimeout(timeout);
});
return deferred.promise;
}

protected killWorker(worker: ParserWorker): void {
protected terminateWorker(worker: ParserWorker): void {
worker.terminate();
const index = this.workerPool.indexOf(worker);
if (index >= 0) {
Expand All @@ -121,15 +120,12 @@ export abstract class AbstractThreadedAsyncParser implements AsyncParser {
}
}
const deferred = new Deferred<ParserWorker>();
const cancellation = cancelToken.onCancellationRequested(() => {
cancelToken.onCancellationRequested(() => {
const index = this.queue.indexOf(deferred);
if (index >= 0) {
this.queue.splice(index, 1);
}
deferred.reject(OperationCancelled);
});
deferred.finally(() => {
cancellation.dispose();
deferred.reject('OperationCancelled');
});
this.queue.push(deferred);
return deferred.promise;
Expand Down
11 changes: 0 additions & 11 deletions packages/langium/src/utils/promise-utils.ts
Expand Up @@ -92,24 +92,13 @@ export class Deferred<T = void> {
resolve: (value: T) => this;
reject: (err?: unknown) => this;

private callbacks: Array<() => void> = [];

finally(callback: () => void): this {
this.callbacks.push(callback);
return this;
}

promise = new Promise<T>((resolve, reject) => {
this.resolve = (arg) => {
resolve(arg);
this.callbacks.forEach(cb => cb());
this.callbacks = [];
return this;
};
this.reject = (err) => {
reject(err);
this.callbacks.forEach(cb => cb());
this.callbacks = [];
return this;
};
});
Expand Down

0 comments on commit 194ec01

Please sign in to comment.