arduino-ide/arduino-ide-extension/src/node/grpc-client-provider.ts
Francesco Stasi 49d12d99ff
IDE to run CLI with auto assigned port (#673)
* get daemon port from CLI stdout

* config-service to use CLI daemon port

* updating LS

* fixed tests

* fix upload blocked when selectedBoard.port is undefined

* bump arduino-cli to 0.20.2

Co-authored-by: Alberto Iannaccone <a.iannaccone@arduino.cc>
2021-12-09 15:08:26 +01:00

79 lines
2.1 KiB
TypeScript

import { inject, injectable, postConstruct } from 'inversify';
import { ILogger } from '@theia/core/lib/common/logger';
import { MaybePromise } from '@theia/core/lib/common/types';
import { ConfigServiceImpl } from './config-service-impl';
import { ArduinoDaemonImpl } from './arduino-daemon-impl';
@injectable()
export abstract class GrpcClientProvider<C> {
@inject(ILogger)
protected readonly logger: ILogger;
@inject(ArduinoDaemonImpl)
protected readonly daemon: ArduinoDaemonImpl;
@inject(ConfigServiceImpl)
protected readonly configService: ConfigServiceImpl;
protected _port: string | number | undefined;
protected _client: C | Error | undefined;
@postConstruct()
protected init(): void {
const updateClient = () => {
this.reconcileClient();
};
this.configService.onConfigChange(updateClient);
this.daemon.ready.then(updateClient);
this.daemon.onDaemonStopped(() => {
if (this._client && !(this._client instanceof Error)) {
this.close(this._client);
}
this._client = undefined;
this._port = undefined;
});
}
async client(): Promise<C | Error | undefined> {
try {
await this.daemon.ready;
return this._client;
} catch (error) {
return error;
}
}
protected async reconcileClient(): Promise<void> {
const port = await this.daemon.getPort();
if (this._port === port) {
return; // Nothing to do.
}
this._port = port;
if (this._client && !(this._client instanceof Error)) {
this.close(this._client);
this._client = undefined;
}
if (this._port) {
try {
const client = await this.createClient(this._port);
this._client = client;
} catch (error) {
this.logger.error('Could not create client for gRPC.', error);
this._client = error;
}
}
}
protected abstract createClient(port: string | number): MaybePromise<C>;
protected abstract close(client: C): void;
protected get channelOptions(): Record<string, unknown> {
return {
'grpc.max_send_message_length': 512 * 1024 * 1024,
'grpc.max_receive_message_length': 512 * 1024 * 1024,
};
}
}