Skip to content

Commit

Permalink
Improve startup time
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew committed Jan 23, 2024
1 parent 346f0d5 commit 3d40610
Showing 1 changed file with 33 additions and 31 deletions.
64 changes: 33 additions & 31 deletions packages/langium/src/parser/async-parser.ts
Expand Up @@ -46,7 +46,7 @@ export abstract class AbstractThreadedAsyncParser implements AsyncParser {

/**
* The thread count determines how many threads are used to parse files in parallel.
* The default value is 8. Decreasing this value increases startup performance, but decreases parsing performance.
* The default value is 8. Decreasing this value increases startup performance, but decreases parallel parsing performance.
*/
protected threadCount = 8;
/**
Expand All @@ -63,6 +63,22 @@ export abstract class AbstractThreadedAsyncParser implements AsyncParser {
this.hydrator = services.serializer.Hydrator;
}

protected initializeWorkers(): void {
while (this.workerPool.length < this.threadCount) {
const worker = this.createWorker();
worker.onReady(() => {
if (this.queue.length > 0) {
const deferred = this.queue.shift();
if (deferred) {
worker.lock();
deferred.resolve(worker);
}
}
});
this.workerPool.push(worker);
}
}

async parse<T extends AstNode>(text: string, cancelToken: CancellationToken): Promise<ParseResult<T>> {
const worker = await this.acquireParserWorker(cancelToken);
const deferred = new Deferred<ParseResult<T>>();
Expand Down Expand Up @@ -91,37 +107,23 @@ export abstract class AbstractThreadedAsyncParser implements AsyncParser {
}

protected async acquireParserWorker(cancelToken: CancellationToken): Promise<ParserWorker> {
if (this.workerPool.length < this.threadCount) {
const worker = this.createWorker();
worker.onReady(() => {
if (this.queue.length > 0) {
const deferred = this.queue.shift();
if (deferred) {
worker.lock();
deferred.resolve(worker);
}
}
});
this.workerPool.push(worker);
return worker;
} else {
for (const worker of this.workerPool) {
if (worker.ready) {
worker.lock();
return worker;
}
this.initializeWorkers();
for (const worker of this.workerPool) {
if (worker.ready) {
worker.lock();
return worker;
}
const deferred = new Deferred<ParserWorker>();
deferred.disposables.push(cancelToken.onCancellationRequested(() => {
const index = this.queue.indexOf(deferred);
if (index >= 0) {
this.queue.splice(index, 1);
}
deferred.reject(OperationCancelled);
}));
this.queue.push(deferred);
return deferred.promise;
}
const deferred = new Deferred<ParserWorker>();
deferred.disposables.push(cancelToken.onCancellationRequested(() => {
const index = this.queue.indexOf(deferred);
if (index >= 0) {
this.queue.splice(index, 1);
}
deferred.reject(OperationCancelled);
}));
this.queue.push(deferred);
return deferred.promise;
}

protected abstract getWorkerPath(): string;
Expand All @@ -138,7 +140,7 @@ export class ParserWorker {
protected readonly onReadyEmitter = new Emitter<void>();

protected deferred = new Deferred<ParseResult>();
protected _ready: boolean = false;
protected _ready: boolean = true;

get ready(): boolean {
return this._ready;
Expand Down

0 comments on commit 3d40610

Please sign in to comment.