Fixed a race condition when requestng core client.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
Akos Kitta
2019-05-07 11:59:41 +02:00
committed by Christian Weichel
parent e14ac4a396
commit 50c1c7dcb2
4 changed files with 57 additions and 16 deletions

View File

@@ -8,10 +8,13 @@ import URI from '@theia/core/lib/common/uri';
import { CoreClientProvider, Client } from './core-client-provider';
import * as fs from 'fs';
import * as path from 'path';
import * as PQueue from 'p-queue';
@injectable()
export class CoreClientProviderImpl implements CoreClientProvider {
protected readonly clientRequestQueue = new PQueue({ autoStart: true, concurrency: 1 });
@inject(FileSystem)
protected readonly fileSystem: FileSystem;
@@ -21,20 +24,24 @@ export class CoreClientProviderImpl implements CoreClientProvider {
protected clients = new Map<string, Client>();
async getClient(workspaceRootOrResourceUri?: string): Promise<Client> {
const roots = await this.workspaceServiceExt.roots();
if (!workspaceRootOrResourceUri) {
return this.getOrCreateClient(roots[0]);
}
const root = roots
.sort((left, right) => right.length - left.length) // Longest "paths" first
.map(uri => new URI(uri))
.find(uri => uri.isEqualOrParent(new URI(workspaceRootOrResourceUri)));
if (!root) {
console.warn(`Could not retrieve the container workspace root for URI: ${workspaceRootOrResourceUri}.`);
console.warn(`Falling back to ${roots[0]}`);
return this.getOrCreateClient(roots[0]);
}
return this.getOrCreateClient(root.toString());
return this.clientRequestQueue.add(() => new Promise<Client>(async resolve => {
const roots = await this.workspaceServiceExt.roots();
if (!workspaceRootOrResourceUri) {
resolve(this.getOrCreateClient(roots[0]));
return;
}
const root = roots
.sort((left, right) => right.length - left.length) // Longest "paths" first
.map(uri => new URI(uri))
.find(uri => uri.isEqualOrParent(new URI(workspaceRootOrResourceUri)));
if (!root) {
console.warn(`Could not retrieve the container workspace root for URI: ${workspaceRootOrResourceUri}.`);
console.warn(`Falling back to ${roots[0]}`);
resolve(this.getOrCreateClient(roots[0]));
return;
}
resolve(this.getOrCreateClient(root.toString()));
}));
}
protected async getOrCreateClient(rootUri: string): Promise<Client> {

View File

@@ -1,10 +1,23 @@
import { injectable } from 'inversify';
import { injectable, inject } from 'inversify';
import { Library, LibraryService } from '../common/protocol/library-service';
import { CoreClientProvider } from './core-client-provider';
import { LibrarySearchReq, LibrarySearchResp } from './cli-protocol/lib_pb';
@injectable()
export class LibraryServiceImpl implements LibraryService {
@inject(CoreClientProvider)
protected readonly coreClientProvider: CoreClientProvider;
async search(options: { query?: string; }): Promise<{ items: Library[] }> {
const { client, instance } = await this.coreClientProvider.getClient();
const req = new LibrarySearchReq();
req.setQuery(options.query || '');
req.setInstance(instance);
const resp = await new Promise<LibrarySearchResp>((resolve, reject) => client.librarySearch(req, (err, resp) => !!err ? reject(err) : resolve(resp)));
console.log(resp.getSearchOutputList());
const { query } = options;
const allItems: Library[] = [
<Library>{