mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 20:13:32 +01:00
Call extension deactivate(), dispose subscriptions on extension host shutdown
This commit is contained in:
@@ -104,16 +104,45 @@ interface ITestRunner {
|
||||
|
||||
export class PluginHostMain {
|
||||
|
||||
private _isTerminating: boolean;
|
||||
|
||||
constructor(
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IPluginService private pluginService: IPluginService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
) {}
|
||||
) {
|
||||
this._isTerminating = false;
|
||||
}
|
||||
|
||||
public start(): TPromise<void> {
|
||||
return this.readPlugins();
|
||||
}
|
||||
|
||||
public terminate(): void {
|
||||
if (this._isTerminating) {
|
||||
// we are already shutting down...
|
||||
return;
|
||||
}
|
||||
this._isTerminating = true;
|
||||
|
||||
try {
|
||||
let allExtensions = PluginsRegistry.getAllPluginDescriptions();
|
||||
let allExtensionsIds = allExtensions.map(ext => ext.id);
|
||||
let activatedExtensions = allExtensionsIds.filter(id => this.pluginService.isActivated(id));
|
||||
|
||||
activatedExtensions.forEach((extensionId) => {
|
||||
this.pluginService.deactivate(extensionId);
|
||||
});
|
||||
} catch(err) {
|
||||
// TODO: write to log once we have one
|
||||
}
|
||||
|
||||
// Give extensions 1 second to wrap up any async dispose, then exit
|
||||
setTimeout(() => {
|
||||
exit()
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private readPlugins(): TPromise<void> {
|
||||
let collector = new PluginsMessageCollector();
|
||||
let env = this.contextService.getConfiguration().env;
|
||||
|
||||
@@ -16,8 +16,14 @@ interface IRendererConnection {
|
||||
initData: IInitData;
|
||||
}
|
||||
|
||||
// This calls exit directly in case the initialization is not finished and we need to exit
|
||||
// Otherwise, if initialization completed we go to pluginHostMain.terminate()
|
||||
var onTerminate = function() {
|
||||
exit();
|
||||
};
|
||||
|
||||
function connectToRenderer(): TPromise<IRendererConnection> {
|
||||
return new TPromise((c, e) => {
|
||||
return new TPromise<IRendererConnection>((c, e) => {
|
||||
const stats: number[] = [];
|
||||
|
||||
// Listen init data message
|
||||
@@ -28,7 +34,13 @@ function connectToRenderer(): TPromise<IRendererConnection> {
|
||||
});
|
||||
|
||||
// Listen to all other messages
|
||||
process.on('message', msg => remoteCom.handle(msg));
|
||||
process.on('message', (msg) => {
|
||||
if (msg.type === '__$terminate') {
|
||||
onTerminate();
|
||||
return;
|
||||
}
|
||||
remoteCom.handle(msg);
|
||||
});
|
||||
|
||||
// Print a console message when rejection isn't handled. For details
|
||||
// see https://nodejs.org/api/process.html#process_event_unhandledrejection
|
||||
@@ -50,7 +62,7 @@ function connectToRenderer(): TPromise<IRendererConnection> {
|
||||
try {
|
||||
process.kill(msg.parentPid, 0); // throws an exception if the main process doesn't exist anymore.
|
||||
} catch (e) {
|
||||
exit();
|
||||
onTerminate();
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
@@ -86,6 +98,10 @@ TPromise.join<any>([connectToRenderer(), connectToSharedProcess()])
|
||||
const instantiationService = createServices(renderer.remoteCom, renderer.initData, sharedProcessClient);
|
||||
const pluginHostMain = instantiationService.createInstance(PluginHostMain);
|
||||
|
||||
onTerminate = () => {
|
||||
pluginHostMain.terminate();
|
||||
};
|
||||
|
||||
pluginHostMain.start()
|
||||
.done(null, err => console.error(err));
|
||||
});
|
||||
Reference in New Issue
Block a user