8000 [NO_MERGE][WIP] Startup time by kittaakos · Pull Request #1004 · arduino/arduino-ide · GitHub
[go: up one dir, main page]

Skip to content

[NO_MERGE][WIP] Startup time #1004

New issue

Have a question about this project? Sign up for a free GitHub account to open 8000 an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
db26148
Dropped Git and the custom layout restorer.
May 20, 2022
5da4b1a
duration decorator.
May 20, 2022
986d597
get ws root withot check.
May 20, 2022
8c95086
Enabled `noImplicitOverride` TS option.
May 20, 2022
307546c
Switched to sketchRef for examples and builtins.
May 20, 2022
77d7416
can disable splash.
May 21, 2022
99caaa8
speed up examples load.
May 21, 2022
9301121
disabled old way of computing the examples.
May 21, 2022
23a1693
do not resolve all sketches as possible ws roots.
May 21, 2022
ba1ff1a
Generate bultin examples structure at build time.
May 21, 2022
5cecaab
load the list widget content only when activated.
May 23, 2022
6179300
reimpl. discovering sketches from the sketchbook
May 23, 2022
17b5646
dropped old way of calculating sketchbook content
May 23, 2022
7e5be19
fixed typo in logs.
May 23, 2022
cf17ce1
changed how to init cli config service.
May 23, 2022
61279fe
run update after show.
May 24, 2022
3e583a7
fall back to new temp sketch URI when no recent WS
May 24, 2022
d5fabc1
customized JSON schema store, editor navigation history, and preferen…
May 24, 2022
fdca524
launch config to start with dev tools + w/o splash
May 24, 2022
dbf635a
defer all menu updates before app is ready.
May 24, 2022
8000
7ccb92b
do not parse the CLI log JSON, use as is.
May 24, 2022
67a456d
fixed port for the LS.
May 24, 2022
dc3b748
deferred contributions to start on app ready.
May 24, 2022
ab163a5
disabled "trick" for deferring menu update.
May 24, 2022
469159e
updated translation files.
May 24, 2022
08f6b27
i18n fixup.
May 24, 2022
c81d1c5
removed native grpc dependencies.
May 24, 2022
71bbeda
Can start the IDE with content tracing.
May 25, 2022
ad76045
Skip loading extensions for the Theia about dialog
May 25, 2022
47620ef
Defer running the FW updates.
May 25, 2022
bc3aee6
Do not require the current window on IDE2 start.
May 25, 2022
313c96c
Do not explicitly initialize the layout on start.
May 25, 2022
68afacf
Added missing protobuf dep.
May 27, 2022
c7f2f4f
asynchronous core and lib index update.
May 27, 2022
e27b9f1
:lipstick: improved dev comments.
May 27, 2022
79503ef
removed debug log.
May 27, 2022
8ffee32
run core and lib index updates parallel.
May 27, 2022
efe7399
Use nightly (20220527) CLI and 2.2.0 FW uploader.
May 27, 2022
05af641
Defer loading boards until the app is ready.
May 27, 2022
b947be0
Open devtools when tracing.
May 27, 2022
2fbf3cb
Resolve and cache current sketch.
May 27, 2022
0e4881c
Reverted titleBarStyling for Windows/Linux.
May 31, 2022
644bf14
workaround for the non realpath.
May 31, 2022
ab56005
Relaxed prettier on Windows.
Jun 1, 2022
8a04d47
Workaround for non-realpaths on Windows.
Jun 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
changed how to init cli config service.
on daemon start, the port is broadcasted from BE.

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
  • Loading branch information
Akos Kitta committed May 25, 2022
commit cf17ce189bfffe00f085b1f775f3399e1d41dc9a
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ExecutableService,
Sketch,
LibraryService,
ArduinoDaemon,
} from '../common/protocol';
import { Mutex } from 'async-mutex';
import {
Expand Down Expand Up @@ -172,6 +173,9 @@ export class ArduinoFrontendContribution
@inject(IDEUpdaterDialog)
protected readonly updaterDialog: IDEUpdaterDialog;

@inject(ArduinoDaemon)
protected readonly daemon: ArduinoDaemon;

protected invalidConfigPopup:
| Promise<void | 'No' | 'Yes' | undefined>
| undefined;
Expand Down Expand Up @@ -369,6 +373,10 @@ export class ArduinoFrontendContribution
): Promise<void> {
const release = await this.languageServerStartMutex.acquire();
try {
const port = this.daemon.tryGetPort();
if (!port) {
return;
}
await this.hostedPluginSupport.didStart;
const details = await this.boardsService.getBoardDetails({ fqbn });
if (!details) {
Expand Down Expand Up @@ -416,8 +424,6 @@ export class ArduinoFrontendContribution
this.fileService.fsPath(new URI(lsUri)),
]);

const config = await this.configService.getConfiguration();

this.languageServerFqbn = await Promise.race([
new Promise<undefined>((_, reject) =>
setTimeout(
Expand All @@ -429,7 +435,7 @@ export class ArduinoFrontendContribution
'arduino.languageserver.start',
{
lsPath,
cliDaemonAddr: `localhost:${config.daemon.port}`, // TODO: verify if this port is coming from the BE
cliDaemonAddr: `localhost:${port}`,
clangdPath,
log: currentSketchPath ? currentSketchPath : log,
cliDaemonInstance: '1',
Expand Down
12 changes: 8 additions & 4 deletions arduino-ide-extension/src/browser/notification-center.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
Expand All @@ -23,7 +27,7 @@ export class NotificationCenter
protected readonly server: JsonRpcProxy<NotificationServiceServer>;

protected readonly indexUpdatedEmitter = new Emitter<void>();
protected readonly daemonStartedEmitter = new Emitter<void>();
protected readonly daemonStartedEmitter = new Emitter<string>();
protected readonly daemonStoppedEmitter = new Emitter<void>();
protected readonly configChangedEmitter = new Emitter<{
config: Config | undefined;
Expand Down Expand Up @@ -82,8 +86,8 @@ export class NotificationCenter
this.indexUpdatedEmitter.fire();
}

notifyDaemonStarted(): void {
this.daemonStartedEmitter.fire();
notifyDaemonStarted(port: string): void {
this.daemonStartedEmitter.fire(port);
}

notifyDaemonStopped(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { Disposable } from '@theia/core/lib/common/disposable';
import { StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
import {
Expand All @@ -18,18 +22,22 @@ export class FrontendConnectionStatusService extends TheiaFrontendConnectionStat
@inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter;

protected isRunning = false;
protected connectedPort: string | undefined;

@postConstruct()
protected override async init(): Promise<void> {
this.schedulePing();
try {
this.isRunning = await this.daemon.isRunning();
this.connectedPort = await this.daemon.tryGetPort();
} catch {}
this.notificationCenter.onDaemonStarted(() => (this.isRunning = true));
this.notificationCenter.onDaemonStopped(() => (this.isRunning = false));
this.notificationCenter.onDaemonStarted(
(port) => (this.connectedPort = port)
);
this.notificat 6D40 ionCenter.onDaemonStopped(
() => (this.connectedPort = undefined)
);
this.wsConnectionProvider.onIncomingMessageActivity(() => {
this.updateStatus(this.isRunning);
this.updateStatus(!!this.connectedPort);
this.schedulePing();
});
}
Expand All @@ -43,19 +51,23 @@ export class ApplicationConnectionStatusContribution extends TheiaApplicationCon
@inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter;

protected isRunning = false;
protected connectedPort: string | undefined;

@postConstruct()
protected async init(): Promise<void> {
try {
this.isRunning = await this.daemon.isRunning();
this.connectedPort = await this.daemon.tryGetPort();
} catch {}
this.notificationCenter.onDaemonStarted(() => (this.isRunning = true));
this.notificationCenter.onDaemonStopped(() => (this.isRunning = false));
this.notificationCenter.onDaemonStarted(
(port) => (this.connectedPort = port)
);
this.notificationCenter.onDaemonStopped(
() => (this.connectedPort = undefined)
);
}

protected override onStateChange(state: ConnectionStatus): void {
if (!this.isRunning && state === ConnectionStatus.ONLINE) {
if (!this.connectedPort && state === ConnectionStatus.ONLINE) {
return;
}
super.onStateChange(state);
Expand All @@ -64,11 +76,11 @@ export class ApplicationConnectionStatusContribution extends TheiaApplicationCon
protected override handleOffline(): void {
this.statusBar.setElement('connection-status', {
alignment: StatusBarAlignment.LEFT,
text: this.isRunning
text: this.connectedPort
? nls.localize('theia/core/offline', 'Offline')
: '$(bolt) ' +
nls.localize('theia/core/daemonOffline', 'CLI Daemon Offline'),
tooltip: this.isRunning
tooltip: this.connectedPort
? nls.localize(
'theia/core/cannotConnectBackend',
'Cannot connect to the backend.'
Expand Down
11 changes: 10 additions & 1 deletion arduino-ide-extension/src/common/protocol/arduino-daemon.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
export const ArduinoDaemonPath = '/services/arduino-daemon';
export const ArduinoDaemon = Symbol('ArduinoDaemon');
export interface ArduinoDaemon {
isRunning(): Promise<boolean>;
/**
* Returns with a promise that resolves with the port
* of the CLI daemon when it's up and running.
*/
getPort(): Promise<string>;
/**
* Unlike `getPort` this method returns with a promise
* that resolves to `undefined` when the daemon is not running.
* Otherwise resolves to the CLI daemon port.
*/
tryGetPort(): Promise<string | undefined>;
}
5 changes: 0 additions & 5 deletions arduino-ide-extension/src/common/protocol/config-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ export interface ConfigService {
getCliConfigFileUri(): Promise<string>;
getConfiguration(): Promise<Config>;
setConfiguration(config: Config): Promise<void>;
isInDataDir(uri: string): Promise<boolean>;
isInSketchDir(uri: string): Promise<boolean>;
}

export interface Daemon {
Expand Down Expand Up @@ -115,10 +113,8 @@ export interface Config {
readonly locale: string;
readonly sketchDirUri: string;
readonly dataDirUri: string;
readonly downloadsDirUri: string;
readonly additionalUrls: AdditionalUrls;
readonly network: Network;
readonly daemon: Daemon;
}
export namespace Config {
export function sameAs(left: Config, right: Config): boolean {
Expand All @@ -135,7 +131,6 @@ export namespace Config {
return (
left.locale === right.locale &&
left.dataDirUri === right.dataDirUri &&
left.downloadsDirUri === right.downloadsDirUri &&
left.sketchDirUri === right.sketchDirUri &&
Network.sameAs(left.network, right.network)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {

export interface NotificationServiceClient {
notifyIndexUpdated(): void;
notifyDaemonStarted(): void;
notifyDaemonStarted(port: string): void;
notifyDaemonStopped(): void;
notifyConfigChanged(event: { config: Config | undefined }): void;
notifyPlatformInstalled(event: { item: BoardsPackage }): void;
Expand Down
37 changes: 17 additions & 20 deletions arduino-ide-extension/src/node/arduino-daemon-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ export class ArduinoDaemonImpl
protected readonly notificationService: NotificationServiceServer;

protected readonly toDispose = new DisposableCollection();
protected readonly onDaemonStartedEmitter = new Emitter<void>();
protected readonly onDaemonStartedEmitter = new Emitter<string>();
protected readonly onDaemonStoppedEmitter = new Emitter<void>();

protected _running = false;
protected _ready = new Deferred<void>();
protected _port = new Deferred<string>();
protected _execPath: string | undefined;
protected _port: string;

// Backend application lifecycle.

Expand All @@ -48,12 +47,15 @@ export class ArduinoDaemonImpl

// Daemon API

async isRunning(): Promise<boolean> {
return Promise.resolve(this._running);
async getPort(): Promise<string> {
return this._port.promise;
}

async getPort(): Promise<string> {
return Promise.resolve(this._port);
async tryGetPort(): Promise<string | undefined> {
if (this._running) {
return this._port.promise;
}
return undefined;
}

async startDaemon(): Promise<void> {
Expand All @@ -62,7 +64,6 @@ export class ArduinoDaemonImpl
const cliPath = await this.getExecPath();
this.onData(`Starting daemon from ${cliPath}...`);
const { daemon, port } = await this.spawnDaemonProcess();
this._port = port;
// Watchdog process for terminating the daemon process when the backend app terminates.
spawn(
process.execPath,
Expand All @@ -83,7 +84,7 @@ export class ArduinoDaemonImpl
Disposable.create(() => daemon.kill()),
Disposable.create(() => this.fireDaemonStopped()),
]);
this.fireDaemonStarted();
this.fireDaemonStarted(port);
this.onData('Daemon is running.');
} catch (err) {
this.onData('Failed to start the daemon.');
Expand All @@ -103,18 +104,14 @@ export class ArduinoDaemonImpl
this.toDispose.dispose();
}

get onDaemonStarted(): Event<void> {
get onDaemonStarted(): Event<string> {
return this.onDaemonStartedEmitter.event;
}

get onDaemonStopped(): Event<void> {
return this.onDaemonStoppedEmitter.event;
}

get ready(): Promise<void> {
return this._ready.promise;
}

async getExecPath(): Promise<string> {
if (this._execPath) {
return this._execPath;
Expand Down Expand Up @@ -240,20 +237,20 @@ export class ArduinoDaemonImpl
return ready.promise;
}

protected fireDaemonStarted(): void {
protected fireDaemonStarted(port: string): void {
this._running = true;
this._ready.resolve();
this.onDaemonStartedEmitter.fire();
this.notificationService.notifyDaemonStarted();
this._port.resolve(port);
this.onDaemonStartedEmitter.fire(port);
this.notificationService.notifyDaemonStarted(port);
}

protected fireDaemonStopped(): void {
if (!this._running) {
return;
}
this._running = false;
this._ready.reject(); // Reject all pending.
this._ready = new Deferred<void>();
this._port.reject(); // Reject all pending.
this._port = new Deferred<string>();
this.onDaemonStoppedEmitter.fire();
this.notificationService.notifyDaemonStopped();
}
Expand Down
35 changes: 8 additions & 27 deletions arduino-ide-extension/src/node/cli-config.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,31 @@
import { RecursivePartial } from '@theia/core/lib/common/types';
import { Daemon } from '../common/protocol/config-service';
import { AdditionalUrls } from '../common/protocol';

export const CLI_CONFIG = 'arduino-cli.yaml';

export interface BoardManager {
readonly additional_urls: Array<string>;
readonly additional_urls: AdditionalUrls;
}
export namespace BoardManager {
export function sameAs(
left: RecursivePartial<BoardManager> | undefined,
right: RecursivePartial<BoardManager> | undefined
): boolean {
const leftOrDefault = left || {};
const rightOrDefault = right || {};
const leftUrls = Array.from(new Set(leftOrDefault.additional_urls || []));
const rightUrls = Array.from(new Set(rightOrDefault.additional_urls || []));
if (leftUrls.length !== rightUrls.length) {
return false;
}
return leftUrls.every((url) => rightUrls.indexOf(url) !== -1);
const leftUrls = left?.additional_urls ?? [];
const rightUrls = right?.additional_urls ?? [];
return AdditionalUrls.sameAs(leftUrls, rightUrls);
}
}

export interface Directories {
readonly data: string;
readonly downloads: string;
readonly user: string;
}
export namespace Directories {
export function is(
directories: RecursivePartial<Directories> | undefined
): directories is Directories {
return (
!!directories &&
!!directories.data &&
!!directories.downloads &&
!!directories.user
);
return !!directories && !!directories.data && !!directories.user;
}
export function sameAs(
left: RecursivePartial<Directories> | undefined,
Expand All @@ -48,11 +37,7 @@ export namespace Directories {
if (right === undefined) {
return left === undefined;
}
return (
left.data === right.data &&
left.downloads === right.downloads &&
left.user === right.user
);
return left.data === right.data && left.user === right.user;
}
}

Expand Down Expand Up @@ -111,23 +96,19 @@ export interface CliConfig {
// Bare minimum required CLI config.
export interface DefaultCliConfig extends CliConfig {
directories: Directories;
daemon: Daemon;
}
export namespace DefaultCliConfig {
export function is(
config: RecursivePartial<DefaultCliConfig> | undefined
): config is DefaultCliConfig {
return (
!!config && Directories.is(config.directories) && Daemon.is(config.daemon)
);
return !!config && Directories.is(config.directories);
}
export function sameAs(
left: DefaultCliConfig,
right: DefaultCliConfig
): boolean {
return (
Directories.sameAs(left.directories, right.directories) &&
Daemon.sameAs(left.daemon, right.daemon) &&
BoardManager.sameAs(left.board_manager, right.board_manager) &&
Logging.sameAs(left.logging, right.logging)
);
Expand Down
Loading
0