mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-06-17 17:46:33 +00:00
Fixed LS stops working after OS sleep/wakeup cycle
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
5b486b1480
commit
d7809616a4
@ -54,7 +54,6 @@ import { OutputContribution } from '@theia/output/lib/browser/output-contributio
|
|||||||
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
||||||
import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
|
import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
|
||||||
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
|
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
|
||||||
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
|
||||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||||
import { FileChangeType } from '@theia/filesystem/lib/browser';
|
import { FileChangeType } from '@theia/filesystem/lib/browser';
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||||
@ -75,6 +74,7 @@ import { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-wi
|
|||||||
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
|
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
|
||||||
import { IDEUpdater } from '../common/protocol/ide-updater';
|
import { IDEUpdater } from '../common/protocol/ide-updater';
|
||||||
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
|
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
|
||||||
|
import { HostedPluginEvents } from './hosted-plugin-events';
|
||||||
|
|
||||||
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
||||||
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
||||||
@ -147,8 +147,8 @@ export class ArduinoFrontendContribution
|
|||||||
@inject(ConfigService)
|
@inject(ConfigService)
|
||||||
protected readonly configService: ConfigService;
|
protected readonly configService: ConfigService;
|
||||||
|
|
||||||
@inject(HostedPluginSupport)
|
@inject(HostedPluginEvents)
|
||||||
protected hostedPluginSupport: HostedPluginSupport;
|
protected hostedPluginEvents: HostedPluginEvents;
|
||||||
|
|
||||||
@inject(ExecutableService)
|
@inject(ExecutableService)
|
||||||
protected executableService: ExecutableService;
|
protected executableService: ExecutableService;
|
||||||
@ -317,6 +317,12 @@ export class ArduinoFrontendContribution
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
|
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
|
||||||
|
this.hostedPluginEvents.onPluginsDidStart(() =>
|
||||||
|
start(this.boardsServiceClientImpl.boardsConfig)
|
||||||
|
);
|
||||||
|
this.hostedPluginEvents.onPluginsWillUnload(
|
||||||
|
() => (this.languageServerFqbn = undefined)
|
||||||
|
);
|
||||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||||
if (event.newValue !== event.oldValue) {
|
if (event.newValue !== event.oldValue) {
|
||||||
switch (event.preferenceName) {
|
switch (event.preferenceName) {
|
||||||
@ -371,7 +377,7 @@ export class ArduinoFrontendContribution
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const release = await this.languageServerStartMutex.acquire();
|
const release = await this.languageServerStartMutex.acquire();
|
||||||
try {
|
try {
|
||||||
await this.hostedPluginSupport.didStart;
|
await this.hostedPluginEvents.didStart;
|
||||||
const details = await this.boardsService.getBoardDetails({ fqbn });
|
const details = await this.boardsService.getBoardDetails({ fqbn });
|
||||||
if (!details) {
|
if (!details) {
|
||||||
// Core is not installed for the selected board.
|
// Core is not installed for the selected board.
|
||||||
|
@ -277,6 +277,9 @@ import {
|
|||||||
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
||||||
import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager';
|
import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager';
|
||||||
import { EditorManager } from './theia/editor/editor-manager';
|
import { EditorManager } from './theia/editor/editor-manager';
|
||||||
|
import { HostedPluginEvents } from './hosted-plugin-events';
|
||||||
|
import { HostedPluginSupport } from './theia/plugin-ext/hosted-plugin';
|
||||||
|
import { HostedPluginSupport as TheiaHostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
||||||
|
|
||||||
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||||
|
|
||||||
@ -805,4 +808,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
|
|
||||||
|
bind(HostedPluginSupport).toSelf().inSingletonScope();
|
||||||
|
rebind(TheiaHostedPluginSupport).toService(HostedPluginSupport);
|
||||||
|
bind(HostedPluginEvents).toSelf().inSingletonScope();
|
||||||
|
bind(FrontendApplicationContribution).toService(HostedPluginEvents);
|
||||||
});
|
});
|
||||||
|
74
arduino-ide-extension/src/browser/hosted-plugin-events.ts
Normal file
74
arduino-ide-extension/src/browser/hosted-plugin-events.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { DisposableCollection, Emitter, Event } from '@theia/core';
|
||||||
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
||||||
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||||
|
import { HostedPluginSupport } from './theia/plugin-ext/hosted-plugin';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frontend contribution to watch VS Code extension start/stop events from Theia.
|
||||||
|
*
|
||||||
|
* In Theia, there are no events when a VS Code extension is loaded, started, unloaded, and stopped.
|
||||||
|
* Currently, it's possible to `@inject` the `HostedPluginSupport` service from Theia and `await`
|
||||||
|
* for the `didStart` promise to resolve. But if the OS goes to sleep, the VS Code extensions will
|
||||||
|
* be unloaded and loaded and started again when the OS awakes. Theia reloads the VS Code extensions
|
||||||
|
* after the OS awake event, but the `didStart` promise was already resolved, so IDE2 cannot restart the LS.
|
||||||
|
* This service is meant to work around the limitation of Theia and fire an event every time the VS Code extensions
|
||||||
|
* loaded and started.
|
||||||
|
*/
|
||||||
|
@injectable()
|
||||||
|
export class HostedPluginEvents implements FrontendApplicationContribution {
|
||||||
|
@inject(HostedPluginSupport)
|
||||||
|
private readonly hostedPluginSupport: HostedPluginSupport;
|
||||||
|
|
||||||
|
private firstStart = true;
|
||||||
|
private readonly onPluginsDidStartEmitter = new Emitter<void>();
|
||||||
|
private readonly onPluginsWillUnloadEmitter = new Emitter<void>();
|
||||||
|
private readonly toDispose = new DisposableCollection(
|
||||||
|
this.onPluginsDidStartEmitter,
|
||||||
|
this.onPluginsWillUnloadEmitter
|
||||||
|
);
|
||||||
|
|
||||||
|
onStart(): void {
|
||||||
|
this.hostedPluginSupport.onDidLoad(() => {
|
||||||
|
// Fire the first event, when `didStart` resolves.
|
||||||
|
if (!this.firstStart) {
|
||||||
|
console.debug('HostedPluginEvents', "Received 'onDidLoad' event.");
|
||||||
|
this.onPluginsDidStartEmitter.fire();
|
||||||
|
} else {
|
||||||
|
console.debug(
|
||||||
|
'HostedPluginEvents',
|
||||||
|
"Received 'onDidLoad' event before the first start. Skipping."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.hostedPluginSupport.didStart.then(() => {
|
||||||
|
console.debug('HostedPluginEvents', "Hosted plugins 'didStart'.");
|
||||||
|
if (!this.firstStart) {
|
||||||
|
throw new Error(
|
||||||
|
'Unexpectedly received a `didStart` event after the first start.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.firstStart = false;
|
||||||
|
this.onPluginsDidStartEmitter.fire();
|
||||||
|
});
|
||||||
|
this.hostedPluginSupport.onDidCloseConnection(() => {
|
||||||
|
console.debug('HostedPluginEvents', "Received 'onDidCloseConnection'.");
|
||||||
|
this.onPluginsWillUnloadEmitter.fire();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onStop(): void {
|
||||||
|
this.toDispose.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
get onPluginsDidStart(): Event<void> {
|
||||||
|
return this.onPluginsDidStartEmitter.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
get onPluginsWillUnload(): Event<void> {
|
||||||
|
return this.onPluginsWillUnloadEmitter.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
get didStart(): Promise<void> {
|
||||||
|
return this.hostedPluginSupport.didStart;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
import { Emitter, Event, JsonRpcProxy } from '@theia/core';
|
||||||
|
import { injectable, interfaces } from '@theia/core/shared/inversify';
|
||||||
|
import { HostedPluginServer } from '@theia/plugin-ext/lib/common/plugin-protocol';
|
||||||
|
import { HostedPluginSupport as TheiaHostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
||||||
|
@injectable()
|
||||||
|
export class HostedPluginSupport extends TheiaHostedPluginSupport {
|
||||||
|
private readonly onDidLoadEmitter = new Emitter<void>();
|
||||||
|
private readonly onDidCloseConnectionEmitter = new Emitter<void>();
|
||||||
|
|
||||||
|
override onStart(container: interfaces.Container): void {
|
||||||
|
super.onStart(container);
|
||||||
|
this.hostedPluginServer.onDidCloseConnection(() =>
|
||||||
|
this.onDidCloseConnectionEmitter.fire()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async doLoad(): Promise<void> {
|
||||||
|
await super.doLoad();
|
||||||
|
this.onDidLoadEmitter.fire(); // Unlike Theia, IDE2 fires an event after loading the VS Code extensions.
|
||||||
|
}
|
||||||
|
|
||||||
|
get onDidLoad(): Event<void> {
|
||||||
|
return this.onDidLoadEmitter.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
get onDidCloseConnection(): Event<void> {
|
||||||
|
return this.onDidCloseConnectionEmitter.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get hostedPluginServer(): JsonRpcProxy<HostedPluginServer> {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
return (this as any).server;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user