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

@@ -9,7 +9,9 @@
"@theia/filesystem": "next",
"@theia/languages": "next",
"@theia/monaco": "next",
"@theia/workspace": "next"
"@theia/workspace": "next",
"@types/p-queue": "^3.2.1",
"p-queue": "^5.0.0"
},
"scripts": {
"generate-protoc": "./scripts/generate-protoc.sh",

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>{