mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-15 07:16:38 +00:00
Let DI framework create MonitorService
instances
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
f4a68e793e
commit
7fed8febf1
@ -236,26 +236,14 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(MonitorServiceFactory).toFactory(
|
bind(MonitorServiceFactory).toFactory(
|
||||||
({ container }) =>
|
({ container }) =>
|
||||||
(options: MonitorServiceFactoryOptions) => {
|
(options: MonitorServiceFactoryOptions) => {
|
||||||
const logger = container.get<ILogger>(ILogger);
|
const child = container.createChild();
|
||||||
|
child
|
||||||
const monitorSettingsProvider = container.get<MonitorSettingsProvider>(
|
.bind<MonitorServiceFactoryOptions>(MonitorServiceFactoryOptions)
|
||||||
MonitorSettingsProvider
|
.toConstantValue({
|
||||||
);
|
...options,
|
||||||
|
});
|
||||||
const webSocketProvider =
|
child.bind(MonitorService).toSelf();
|
||||||
container.get<WebSocketProvider>(WebSocketProvider);
|
return child.get<MonitorService>(MonitorService);
|
||||||
|
|
||||||
const { board, port, coreClientProvider, monitorID } = options;
|
|
||||||
|
|
||||||
return new MonitorService(
|
|
||||||
logger,
|
|
||||||
monitorSettingsProvider,
|
|
||||||
webSocketProvider,
|
|
||||||
board,
|
|
||||||
port,
|
|
||||||
coreClientProvider,
|
|
||||||
monitorID
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ export namespace CoreClientProvider {
|
|||||||
@injectable()
|
@injectable()
|
||||||
export abstract class CoreClientAware {
|
export abstract class CoreClientAware {
|
||||||
@inject(CoreClientProvider)
|
@inject(CoreClientProvider)
|
||||||
protected readonly coreClientProvider: CoreClientProvider; // TODO: should be `private`, fix injection in subclasses. (https://github.com/arduino/arduino-ide/issues/1161)
|
private readonly coreClientProvider: CoreClientProvider;
|
||||||
/**
|
/**
|
||||||
* Returns with a promise that resolves when the core client is initialized and ready.
|
* Returns with a promise that resolves when the core client is initialized and ready.
|
||||||
*/
|
*/
|
||||||
|
@ -317,7 +317,6 @@ export class MonitorManager extends CoreClientAware {
|
|||||||
board,
|
board,
|
||||||
port,
|
port,
|
||||||
monitorID,
|
monitorID,
|
||||||
coreClientProvider: this.coreClientProvider,
|
|
||||||
});
|
});
|
||||||
this.monitorServices.set(monitorID, monitor);
|
this.monitorServices.set(monitorID, monitor);
|
||||||
monitor.onDispose(
|
monitor.onDispose(
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
import { Board, Port } from '../common/protocol';
|
import type { Board, Port } from '../common/protocol';
|
||||||
import { CoreClientProvider } from './core-client-provider';
|
import type { MonitorService } from './monitor-service';
|
||||||
import { MonitorService } from './monitor-service';
|
|
||||||
|
|
||||||
export const MonitorServiceFactory = Symbol('MonitorServiceFactory');
|
export const MonitorServiceFactory = Symbol('MonitorServiceFactory');
|
||||||
export interface MonitorServiceFactory {
|
export interface MonitorServiceFactory {
|
||||||
(options: {
|
(options: MonitorServiceFactoryOptions): MonitorService;
|
||||||
board: Board;
|
|
||||||
port: Port;
|
|
||||||
monitorID: string;
|
|
||||||
coreClientProvider: CoreClientProvider;
|
|
||||||
}): MonitorService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MonitorServiceFactoryOptions = Symbol(
|
||||||
|
'MonitorServiceFactoryOptions'
|
||||||
|
);
|
||||||
export interface MonitorServiceFactoryOptions {
|
export interface MonitorServiceFactoryOptions {
|
||||||
board: Board;
|
board: Board;
|
||||||
port: Port;
|
port: Port;
|
||||||
monitorID: string;
|
monitorID: string;
|
||||||
coreClientProvider: CoreClientProvider;
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ClientDuplexStream } from '@grpc/grpc-js';
|
import { ClientDuplexStream } from '@grpc/grpc-js';
|
||||||
import { Disposable, Emitter, ILogger } from '@theia/core';
|
import { Disposable, Emitter, ILogger } from '@theia/core';
|
||||||
import { inject, named } from '@theia/core/shared/inversify';
|
import { inject, named, postConstruct } from '@theia/core/shared/inversify';
|
||||||
import { Board, Port, Status, Monitor } from '../common/protocol';
|
import { Board, Port, Status, Monitor } from '../common/protocol';
|
||||||
import {
|
import {
|
||||||
EnumerateMonitorPortSettingsRequest,
|
EnumerateMonitorPortSettingsRequest,
|
||||||
@ -10,7 +10,7 @@ import {
|
|||||||
MonitorRequest,
|
MonitorRequest,
|
||||||
MonitorResponse,
|
MonitorResponse,
|
||||||
} from './cli-protocol/cc/arduino/cli/commands/v1/monitor_pb';
|
} from './cli-protocol/cc/arduino/cli/commands/v1/monitor_pb';
|
||||||
import { CoreClientAware, CoreClientProvider } from './core-client-provider';
|
import { CoreClientAware } from './core-client-provider';
|
||||||
import { WebSocketProvider } from './web-socket/web-socket-provider';
|
import { WebSocketProvider } from './web-socket/web-socket-provider';
|
||||||
import { Port as gRPCPort } from 'arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
import { Port as gRPCPort } from 'arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||||
import {
|
import {
|
||||||
@ -19,6 +19,7 @@ import {
|
|||||||
MonitorSettingsProvider,
|
MonitorSettingsProvider,
|
||||||
} from './monitor-settings/monitor-settings-provider';
|
} from './monitor-settings/monitor-settings-provider';
|
||||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
|
import { MonitorServiceFactoryOptions } from './monitor-service-factory';
|
||||||
|
|
||||||
export const MonitorServiceName = 'monitor-service';
|
export const MonitorServiceName = 'monitor-service';
|
||||||
type DuplexHandlerKeys =
|
type DuplexHandlerKeys =
|
||||||
@ -33,55 +34,63 @@ interface DuplexHandler {
|
|||||||
callback: (...args: any) => void;
|
callback: (...args: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_WRITE_TO_STREAM_TRIES = 10;
|
||||||
|
const WRITE_TO_STREAM_TIMEOUT_MS = 30000;
|
||||||
|
|
||||||
export class MonitorService extends CoreClientAware implements Disposable {
|
export class MonitorService extends CoreClientAware implements Disposable {
|
||||||
|
@inject(ILogger)
|
||||||
|
@named(MonitorServiceName)
|
||||||
|
private readonly logger: ILogger;
|
||||||
|
|
||||||
|
@inject(MonitorSettingsProvider)
|
||||||
|
private readonly monitorSettingsProvider: MonitorSettingsProvider;
|
||||||
|
|
||||||
|
@inject(WebSocketProvider)
|
||||||
|
private readonly webSocketProvider: WebSocketProvider;
|
||||||
|
|
||||||
// Bidirectional gRPC stream used to receive and send data from the running
|
// Bidirectional gRPC stream used to receive and send data from the running
|
||||||
// pluggable monitor managed by the Arduino CLI.
|
// pluggable monitor managed by the Arduino CLI.
|
||||||
protected duplex: ClientDuplexStream<MonitorRequest, MonitorResponse> | null;
|
private duplex: ClientDuplexStream<MonitorRequest, MonitorResponse> | null;
|
||||||
|
|
||||||
// Settings used by the currently running pluggable monitor.
|
// Settings used by the currently running pluggable monitor.
|
||||||
// They can be freely modified while running.
|
// They can be freely modified while running.
|
||||||
protected settings: MonitorSettings = {};
|
private settings: MonitorSettings = {};
|
||||||
|
|
||||||
// List of messages received from the running pluggable monitor.
|
// List of messages received from the running pluggable monitor.
|
||||||
// These are flushed from time to time to the frontend.
|
// These are flushed from time to time to the frontend.
|
||||||
protected messages: string[] = [];
|
private messages: string[] = [];
|
||||||
|
|
||||||
// Handles messages received from the frontend via websocket.
|
// Handles messages received from the frontend via websocket.
|
||||||
protected onMessageReceived?: Disposable;
|
private onMessageReceived?: Disposable;
|
||||||
|
|
||||||
// Sends messages to the frontend from time to time.
|
// Sends messages to the frontend from time to time.
|
||||||
protected flushMessagesInterval?: NodeJS.Timeout;
|
private flushMessagesInterval?: NodeJS.Timeout;
|
||||||
|
|
||||||
// Triggered each time the number of clients connected
|
// Triggered each time the number of clients connected
|
||||||
// to the this service WebSocket changes.
|
// to the this service WebSocket changes.
|
||||||
protected onWSClientsNumberChanged?: Disposable;
|
private onWSClientsNumberChanged?: Disposable;
|
||||||
|
|
||||||
// Used to notify that the monitor is being disposed
|
// Used to notify that the monitor is being disposed
|
||||||
protected readonly onDisposeEmitter = new Emitter<void>();
|
private readonly onDisposeEmitter = new Emitter<void>();
|
||||||
readonly onDispose = this.onDisposeEmitter.event;
|
readonly onDispose = this.onDisposeEmitter.event;
|
||||||
|
|
||||||
protected _initialized = new Deferred<void>();
|
private _initialized = new Deferred<void>();
|
||||||
protected creating: Deferred<Status>;
|
private creating: Deferred<Status>;
|
||||||
|
private readonly board: Board;
|
||||||
MAX_WRITE_TO_STREAM_TRIES = 10;
|
private readonly port: Port;
|
||||||
WRITE_TO_STREAM_TIMEOUT_MS = 30000;
|
private readonly monitorID: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(ILogger)
|
@inject(MonitorServiceFactoryOptions) options: MonitorServiceFactoryOptions
|
||||||
@named(MonitorServiceName)
|
|
||||||
protected readonly logger: ILogger,
|
|
||||||
@inject(MonitorSettingsProvider)
|
|
||||||
protected readonly monitorSettingsProvider: MonitorSettingsProvider,
|
|
||||||
@inject(WebSocketProvider)
|
|
||||||
protected readonly webSocketProvider: WebSocketProvider,
|
|
||||||
|
|
||||||
private readonly board: Board,
|
|
||||||
private readonly port: Port,
|
|
||||||
protected override readonly coreClientProvider: CoreClientProvider,
|
|
||||||
private readonly monitorID: string
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this.board = options.board;
|
||||||
|
this.port = options.port;
|
||||||
|
this.monitorID = options.monitorID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@postConstruct()
|
||||||
|
protected init(): void {
|
||||||
this.onWSClientsNumberChanged =
|
this.onWSClientsNumberChanged =
|
||||||
this.webSocketProvider.onClientsNumberChanged(async (clients: number) => {
|
this.webSocketProvider.onClientsNumberChanged(async (clients: number) => {
|
||||||
if (clients === 0) {
|
if (clients === 0) {
|
||||||
@ -94,7 +103,7 @@ export class MonitorService extends CoreClientAware implements Disposable {
|
|||||||
this.updateClientsSettings(this.settings);
|
this.updateClientsSettings(this.settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.portMonitorSettings(port.protocol, board.fqbn!).then(
|
this.portMonitorSettings(this.port.protocol, this.board.fqbn!).then(
|
||||||
async (settings) => {
|
async (settings) => {
|
||||||
this.settings = {
|
this.settings = {
|
||||||
...this.settings,
|
...this.settings,
|
||||||
@ -258,8 +267,8 @@ export class MonitorService extends CoreClientAware implements Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pollWriteToStream(request: MonitorRequest): Promise<boolean> {
|
pollWriteToStream(request: MonitorRequest): Promise<boolean> {
|
||||||
let attemptsRemaining = this.MAX_WRITE_TO_STREAM_TRIES;
|
let attemptsRemaining = MAX_WRITE_TO_STREAM_TRIES;
|
||||||
const writeTimeoutMs = this.WRITE_TO_STREAM_TIMEOUT_MS;
|
const writeTimeoutMs = WRITE_TO_STREAM_TIMEOUT_MS;
|
||||||
|
|
||||||
const createWriteToStreamExecutor =
|
const createWriteToStreamExecutor =
|
||||||
(duplex: ClientDuplexStream<MonitorRequest, MonitorResponse>) =>
|
(duplex: ClientDuplexStream<MonitorRequest, MonitorResponse>) =>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user