Skip to content

Commit 9c36fe1

Browse files
author
Akos Kitta
committed
fix: drop obsolete gRPC settings service client
Signed-off-by: Akos Kitta <[email protected]>
1 parent 3ae7aed commit 9c36fe1

12 files changed

+110
-93
lines changed

arduino-ide-extension/src/browser/contributions/ino-language.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,7 @@ export class InoLanguage extends SketchContribution {
196196
forceStart = false
197197
): Promise<void> {
198198
const port = await this.daemon.tryGetPort();
199-
if (!port) {
200-
return;
201-
}
202-
const portNumber = Number.parseInt(port, 10); // TODO: IDE2 APIs should provide a number and not string
203-
if (Number.isNaN(portNumber)) {
199+
if (typeof port !== 'number') {
204200
return;
205201
}
206202
const release = await this.languageServerStartMutex.acquire();
@@ -280,7 +276,7 @@ export class InoLanguage extends SketchContribution {
280276
lsPath,
281277
daemonAddress: {
282278
hostname: 'localhost',
283-
port: portNumber,
279+
port,
284280
instance: 1, // TODO: get it from the backend
285281
},
286282
clangdPath,

arduino-ide-extension/src/browser/notification-center.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class NotificationCenter
4646
new Emitter<ProgressMessage>();
4747
private readonly indexUpdateDidFailEmitter =
4848
new Emitter<IndexUpdateDidFailParams>();
49-
private readonly daemonDidStartEmitter = new Emitter<string>();
49+
private readonly daemonDidStartEmitter = new Emitter<number>();
5050
private readonly daemonDidStopEmitter = new Emitter<void>();
5151
private readonly configDidChangeEmitter = new Emitter<ConfigState>();
5252
private readonly platformDidInstallEmitter = new Emitter<{
@@ -136,7 +136,7 @@ export class NotificationCenter
136136
this.indexUpdateDidFailEmitter.fire(params);
137137
}
138138

139-
notifyDaemonDidStart(port: string): void {
139+
notifyDaemonDidStart(port: number): void {
140140
this.daemonDidStartEmitter.fire(port);
141141
}
142142

arduino-ide-extension/src/browser/theia/core/connection-status-service.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ export class DaemonPort implements FrontendApplicationContribution {
7474
@inject(NotificationCenter)
7575
private readonly notificationCenter: NotificationCenter;
7676

77-
private readonly onPortDidChangeEmitter = new Emitter<string | undefined>();
78-
private _port: string | undefined;
77+
private readonly onPortDidChangeEmitter = new Emitter<number | undefined>();
78+
private _port: number | undefined;
7979

8080
onStart(): void {
8181
this.daemon.tryGetPort().then(
@@ -91,15 +91,15 @@ export class DaemonPort implements FrontendApplicationContribution {
9191
this.onPortDidChangeEmitter.dispose();
9292
}
9393

94-
get port(): string | undefined {
94+
get port(): number | undefined {
9595
return this._port;
9696
}
9797

98-
get onDidChangePort(): Event<string | undefined> {
98+
get onDidChangePort(): Event<number | undefined> {
9999
return this.onPortDidChangeEmitter.event;
100100
}
101101

102-
private setPort(port: string | undefined): void {
102+
private setPort(port: number | undefined): void {
103103
const oldPort = this._port;
104104
this._port = port;
105105
if (this._port !== oldPort) {

arduino-ide-extension/src/common/protocol/arduino-daemon.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ export interface ArduinoDaemon {
55
* Returns with a promise that resolves with the port
66
* of the CLI daemon when it's up and running.
77
*/
8-
getPort(): Promise<string>;
8+
getPort(): Promise<number>;
99
/**
1010
* Unlike `getPort` this method returns with a promise
1111
* that resolves to `undefined` when the daemon is not running.
1212
* Otherwise resolves to the CLI daemon port.
1313
*/
14-
tryGetPort(): Promise<string | undefined>;
15-
start(): Promise<string>;
14+
tryGetPort(): Promise<number | undefined>;
15+
start(): Promise<number>;
1616
stop(): Promise<void>;
17-
restart(): Promise<string>;
17+
restart(): Promise<number>;
1818
}

arduino-ide-extension/src/common/protocol/notification-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export interface NotificationServiceClient {
5151
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void;
5252

5353
// Daemon
54-
notifyDaemonDidStart(port: string): void;
54+
notifyDaemonDidStart(port: number): void;
5555
notifyDaemonDidStop(): void;
5656

5757
// CLI config
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { credentials, makeClientConstructor } from '@grpc/grpc-js';
2+
import * as commandsGrpcPb from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
3+
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
4+
5+
export interface CreateClientOptions {
6+
/**
7+
* The port to the Arduino CLI daemon.
8+
*/
9+
readonly port: number;
10+
/**
11+
* Defaults to `'localhost'`.
12+
*/
13+
readonly host?: string;
14+
15+
/**
16+
* gRCP channel options. Defaults to `createDefaultChannelOptions` with `'0.0.0'` `appVersion`
17+
*/
18+
readonly channelOptions?: Record<string, unknown>;
19+
}
20+
21+
export function createDefaultChannelOptions(
22+
appVersion = '0.0.0'
23+
): Record<string, unknown> {
24+
return {
25+
'grpc.max_send_message_length': 512 * 1024 * 1024,
26+
'grpc.max_receive_message_length': 512 * 1024 * 1024,
27+
'grpc.primary_user_agent': `arduino-ide/${appVersion}`,
28+
};
29+
}
30+
31+
export function createArduinoCoreServiceClient(
32+
options: CreateClientOptions
33+
): ArduinoCoreServiceClient {
34+
const {
35+
port,
36+
host = 'localhost',
37+
channelOptions = createDefaultChannelOptions(),
38+
} = options;
39+
const address = `${host}:${port}`;
40+
// https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
41+
const ArduinoCoreServiceClient = makeClientConstructor(
42+
// @ts-expect-error: ignore
43+
commandsGrpcPb['cc.arduino.cli.commands.v1.ArduinoCoreService'],
44+
'ArduinoCoreServiceService'
45+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
46+
) as any;
47+
const client = new ArduinoCoreServiceClient(
48+
address,
49+
credentials.createInsecure(),
50+
channelOptions
51+
) as ArduinoCoreServiceClient;
52+
return client;
53+
}

arduino-ide-extension/src/node/arduino-daemon-impl.ts

+18-12
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ export class ArduinoDaemonImpl
3939
private readonly processUtils: ProcessUtils;
4040

4141
private readonly toDispose = new DisposableCollection();
42-
private readonly onDaemonStartedEmitter = new Emitter<string>();
42+
private readonly onDaemonStartedEmitter = new Emitter<number>();
4343
private readonly onDaemonStoppedEmitter = new Emitter<void>();
4444

4545
private _running = false;
46-
private _port = new Deferred<string>();
46+
private _port = new Deferred<number>();
4747

4848
// Backend application lifecycle.
4949

@@ -53,18 +53,18 @@ export class ArduinoDaemonImpl
5353

5454
// Daemon API
5555

56-
async getPort(): Promise<string> {
56+
async getPort(): Promise<number> {
5757
return this._port.promise;
5858
}
5959

60-
async tryGetPort(): Promise<string | undefined> {
60+
async tryGetPort(): Promise<number | undefined> {
6161
if (this._running) {
6262
return this._port.promise;
6363
}
6464
return undefined;
6565
}
6666

67-
async start(): Promise<string> {
67+
async start(): Promise<number> {
6868
try {
6969
this.toDispose.dispose(); // This will `kill` the previously started daemon process, if any.
7070
const cliPath = this.getExecPath();
@@ -101,13 +101,13 @@ export class ArduinoDaemonImpl
101101
this.toDispose.dispose();
102102
}
103103

104-
async restart(): Promise<string> {
104+
async restart(): Promise<number> {
105105
return this.start();
106106
}
107107

108108
// Backend only daemon API
109109

110-
get onDaemonStarted(): Event<string> {
110+
get onDaemonStarted(): Event<number> {
111111
return this.onDaemonStartedEmitter.event;
112112
}
113113

@@ -150,11 +150,11 @@ export class ArduinoDaemonImpl
150150

151151
protected async spawnDaemonProcess(): Promise<{
152152
daemon: ChildProcess;
153-
port: string;
153+
port: number;
154154
}> {
155155
const args = await this.getSpawnArgs();
156156
const cliPath = this.getExecPath();
157-
const ready = new Deferred<{ daemon: ChildProcess; port: string }>();
157+
const ready = new Deferred<{ daemon: ChildProcess; port: number }>();
158158
const options = {
159159
env: { ...deepClone(process.env), NO_COLOR: String(true) },
160160
};
@@ -195,7 +195,13 @@ export class ArduinoDaemonImpl
195195

196196
if (port.length && address.length) {
197197
grpcServerIsReady = true;
198-
ready.resolve({ daemon, port });
198+
const portNumber = Number.parseInt(port, 10);
199+
if (Number.isNaN(portNumber)) {
200+
ready.reject(
201+
new Error(`Received a NaN port from the CLI: ${port}`)
202+
);
203+
}
204+
ready.resolve({ daemon, port: portNumber });
199205
}
200206
}
201207
});
@@ -225,7 +231,7 @@ export class ArduinoDaemonImpl
225231
return ready.promise;
226232
}
227233

228-
private fireDaemonStarted(port: string): void {
234+
private fireDaemonStarted(port: number): void {
229235
this._running = true;
230236
this._port.resolve(port);
231237
this.onDaemonStartedEmitter.fire(port);
@@ -238,7 +244,7 @@ export class ArduinoDaemonImpl
238244
}
239245
this._running = false;
240246
this._port.reject(); // Reject all pending.
241-
this._port = new Deferred<string>();
247+
this._port = new Deferred<number>();
242248
this.onDaemonStoppedEmitter.fire();
243249
this.notificationService.notifyDaemonDidStop();
244250
}

arduino-ide-extension/src/node/config-service-impl.ts

+13-28
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { promises as fs } from 'node:fs';
22
import { dirname } from 'node:path';
33
import yaml from 'js-yaml';
4-
import * as grpc from '@grpc/grpc-js';
54
import { injectable, inject, named } from '@theia/core/shared/inversify';
65
import URI from '@theia/core/lib/common/uri';
76
import { ILogger } from '@theia/core/lib/common/logger';
@@ -16,18 +15,17 @@ import {
1615
ConfigState,
1716
} from '../common/protocol';
1817
import { spawnCommand } from './exec-util';
19-
import {
20-
MergeRequest,
21-
WriteRequest,
22-
} from './cli-protocol/cc/arduino/cli/settings/v1/settings_pb';
23-
import { SettingsServiceClient } from './cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb';
24-
import * as serviceGrpcPb from './cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb';
2518
import { ArduinoDaemonImpl } from './arduino-daemon-impl';
2619
import { DefaultCliConfig, CLI_CONFIG } from './cli-config';
2720
import { Deferred } from '@theia/core/lib/common/promise-util';
2821
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
2922
import { deepClone, nls } from '@theia/core';
3023
import { ErrnoException } from './utils/errors';
24+
import {
25+
SettingsMergeRequest,
26+
SettingsWriteRequest,
27+
} from './cli-protocol/cc/arduino/cli/commands/v1/settings_pb';
28+
import { createArduinoCoreServiceClient } from './arduino-core-service-client';
3129

3230
const deepmerge = require('deepmerge');
3331

@@ -293,16 +291,16 @@ export class ConfigServiceImpl
293291
}
294292

295293
private async updateDaemon(
296-
port: string | number,
294+
port: number | number,
297295
config: DefaultCliConfig
298296
): Promise<void> {
299-
const client = this.createClient(port);
300-
const req = new MergeRequest();
297+
const client = createArduinoCoreServiceClient({ port });
298+
const req = new SettingsMergeRequest();
301299
const json = JSON.stringify(config, null, 2);
302300
req.setJsonData(json);
303301
this.logger.info(`Updating daemon with 'data': ${json}`);
304302
return new Promise<void>((resolve, reject) => {
305-
client.merge(req, (error) => {
303+
client.settingsMerge(req, (error) => {
306304
try {
307305
if (error) {
308306
reject(error);
@@ -316,14 +314,14 @@ export class ConfigServiceImpl
316314
});
317315
}
318316

319-
private async writeDaemonState(port: string | number): Promise<void> {
320-
const client = this.createClient(port);
321-
const req = new WriteRequest();
317+
private async writeDaemonState(port: number | number): Promise<void> {
318+
const client = createArduinoCoreServiceClient({ port });
319+
const req = new SettingsWriteRequest();
322320
const cliConfigUri = await this.getCliConfigFileUri();
323321
const cliConfigPath = FileUri.fsPath(cliConfigUri);
324322
req.setFilePath(cliConfigPath);
325323
return new Promise<void>((resolve, reject) => {
326-
client.write(req, (error) => {
324+
client.settingsWrite(req, (error) => {
327325
try {
328326
if (error) {
329327
reject(error);
@@ -337,19 +335,6 @@ export class ConfigServiceImpl
337335
});
338336
}
339337

340-
private createClient(port: string | number): SettingsServiceClient {
341-
// https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
342-
const SettingsServiceClient = grpc.makeClientConstructor(
343-
// @ts-expect-error: ignore
344-
serviceGrpcPb['cc.arduino.cli.settings.v1.SettingsService'],
345-
'SettingsServiceService'
346-
) as any;
347-
return new SettingsServiceClient(
348-
`localhost:${port}`,
349-
grpc.credentials.createInsecure()
350-
) as SettingsServiceClient;
351-
}
352-
353338
// #1445
354339
private async ensureUserDirExists(
355340
cliConfig: DefaultCliConfig

0 commit comments

Comments
 (0)