Call extension deactivate(), dispose subscriptions on extension host shutdown

This commit is contained in:
Alex Dima
2015-12-09 13:21:29 +01:00
parent 9f7989d36c
commit 98473e0e88
9 changed files with 109 additions and 7 deletions

View File

@@ -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;

View File

@@ -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));
});