Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d780961

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
Fixed LS stops working after OS sleep/wakeup cycle
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent 5b486b1 commit d780961

File tree

4 files changed

+126
-4
lines changed

4 files changed

+126
-4
lines changed

‎arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ import { OutputContribution } from '@theia/output/lib/browser/output-contributio
5454
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
5555
import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
5656
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
57-
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
5857
import { FileService } from '@theia/filesystem/lib/browser/file-service';
5958
import { FileChangeType } from '@theia/filesystem/lib/browser';
6059
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
@@ -75,6 +74,7 @@ import { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-wi
7574
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
7675
import { IDEUpdater } from '../common/protocol/ide-updater';
7776
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
77+
import { HostedPluginEvents } from './hosted-plugin-events';
7878

7979
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
8080
export const SKIP_IDE_VERSION = 'skipIDEVersion';
@@ -147,8 +147,8 @@ export class ArduinoFrontendContribution
147147
@inject(ConfigService)
148148
protected readonly configService: ConfigService;
149149

150-
@inject(HostedPluginSupport)
151-
protected hostedPluginSupport: HostedPluginSupport;
150+
@inject(HostedPluginEvents)
151+
protected hostedPluginEvents: HostedPluginEvents;
152152

153153
@inject(ExecutableService)
154154
protected executableService: ExecutableService;
@@ -317,6 +317,12 @@ export class ArduinoFrontendContribution
317317
}
318318
};
319319
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
320+
this.hostedPluginEvents.onPluginsDidStart(() =>
321+
start(this.boardsServiceClientImpl.boardsConfig)
322+
);
323+
this.hostedPluginEvents.onPluginsWillUnload(
324+
() => (this.languageServerFqbn = undefined)
325+
);
320326
this.arduinoPreferences.onPreferenceChanged((event) => {
321327
if (event.newValue !== event.oldValue) {
322328
switch (event.preferenceName) {
@@ -371,7 +377,7 @@ export class ArduinoFrontendContribution
371377
): Promise<void> {
372378
const release = await this.languageServerStartMutex.acquire();
373379
try {
374-
await this.hostedPluginSupport.didStart;
380+
await this.hostedPluginEvents.didStart;
375381
const details = await this.boardsService.getBoardDetails({ fqbn });
376382
if (!details) {
377383
// Core is not installed for the selected board.

‎arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ import {
277277
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
278278
import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager';
279279
import { EditorManager } from './theia/editor/editor-manager';
280+
import { HostedPluginEvents } from './hosted-plugin-events';
281+
import { HostedPluginSupport } from './theia/plugin-ext/hosted-plugin';
282+
import { HostedPluginSupport as TheiaHostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
280283

281284
const ElementQueries = require('css-element-queries/src/ElementQueries');
282285

@@ -805,4 +808,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
805808
);
806809
})
807810
.inSingletonScope();
811+
812+
bind(HostedPluginSupport).toSelf().inSingletonScope();
813+
rebind(TheiaHostedPluginSupport).toService(HostedPluginSupport);
814+
bind(HostedPluginEvents).toSelf().inSingletonScope();
815+
bind(FrontendApplicationContribution).toService(HostedPluginEvents);
808816
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { DisposableCollection, Emitter, Event } from '@theia/core';
2+
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
3+
import { inject, injectable } from '@theia/core/shared/inversify';
4+
import { HostedPluginSupport } from './theia/plugin-ext/hosted-plugin';
5+
6+
/**
7+
* Frontend contribution to watch VS Code extension start/stop events from Theia.
8+
*
9+
* In Theia, there are no events when a VS Code extension is loaded, started, unloaded, and stopped.
10+
* Currently, it's possible to `@inject` the `HostedPluginSupport` service from Theia and `await`
11+
* for the `didStart` promise to resolve. But if the OS goes to sleep, the VS Code extensions will
12+
* be unloaded and loaded and started again when the OS awakes. Theia reloads the VS Code extensions
13+
* after the OS awake event, but the `didStart` promise was already resolved, so IDE2 cannot restart the LS.
14+
* This service is meant to work around the limitation of Theia and fire an event every time the VS Code extensions
15+
* loaded and started.
16+
*/
17+
@injectable()
18+
export class HostedPluginEvents implements FrontendApplicationContribution {
19+
@inject(HostedPluginSupport)
20+
private readonly hostedPluginSupport: HostedPluginSupport;
21+
22+
private firstStart = true;
23+
private readonly onPluginsDidStartEmitter = new Emitter<void>();
24+
private readonly onPluginsWillUnloadEmitter = new Emitter<void>();
25+
private readonly toDispose = new DisposableCollection(
26+
this.onPluginsDidStartEmitter,
27+
this.onPluginsWillUnloadEmitter
28+
);
29+
30+
onStart(): void {
31+
this.hostedPluginSupport.onDidLoad(() => {
32+
// Fire the first event, when `didStart` resolves.
33+
if (!this.firstStart) {
34+
console.debug('HostedPluginEvents', "Received 'onDidLoad' event.");
35+
this.onPluginsDidStartEmitter.fire();
36+
} else {
37+
console.debug(
38+
'HostedPluginEvents',
39+
"Received 'onDidLoad' event before the first start. Skipping."
40+
);
41+
}
42+
});
43+
this.hostedPluginSupport.didStart.then(() => {
44+
console.debug('HostedPluginEvents', "Hosted plugins 'didStart'.");
45+
if (!this.firstStart) {
46+
throw new Error(
47+
'Unexpectedly received a `didStart` event after the first start.'
48+
);
49+
}
50+
this.firstStart = false;
51+
this.onPluginsDidStartEmitter.fire();
52+
});
53+
this.hostedPluginSupport.onDidCloseConnection(() => {
54+
console.debug('HostedPluginEvents', "Received 'onDidCloseConnection'.");
55+
this.onPluginsWillUnloadEmitter.fire();
56+
});
57+
}
58+
59+
onStop(): void {
60+
this.toDispose.dispose();
61+
}
62+
63+
get onPluginsDidStart(): Event<void> {
64+
return this.onPluginsDidStartEmitter.event;
65+
}
66+
67+
get onPluginsWillUnload(): Event<void> {
68+
return this.onPluginsWillUnloadEmitter.event;
69+
}
70+
71+
get didStart(): Promise<void> {
72+
return this.hostedPluginSupport.didStart;
73+
}
74+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Emitter, Event, JsonRpcProxy } from '@theia/core';
2+
import { injectable, interfaces } from '@theia/core/shared/inversify';
3+
import { HostedPluginServer } from '@theia/plugin-ext/lib/common/plugin-protocol';
4+
import { HostedPluginSupport as TheiaHostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
5+
@injectable()
6+
export class HostedPluginSupport extends TheiaHostedPluginSupport {
7+
private readonly onDidLoadEmitter = new Emitter<void>();
8+
private readonly onDidCloseConnectionEmitter = new Emitter<void>();
9+
10+
override onStart(container: interfaces.Container): void {
11+
super.onStart(container);
12+
this.hostedPluginServer.onDidCloseConnection(() =>
13+
this.onDidCloseConnectionEmitter.fire()
14+
);
15+
}
16+
17+
protected override async doLoad(): Promise<void> {
18+
await super.doLoad();
19+
this.onDidLoadEmitter.fire(); // Unlike Theia, IDE2 fires an event after loading the VS Code extensions.
20+
}
21+
22+
get onDidLoad(): Event<void> {
23+
return this.onDidLoadEmitter.event;
24+
}
25+
26+
get onDidCloseConnection(): Event<void> {
27+
return this.onDidCloseConnectionEmitter.event;
28+
}
29+
30+
private get hostedPluginServer(): JsonRpcProxy<HostedPluginServer> {
31+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
32+
return (this as any).server;
33+
}
34+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /