Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open 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

Move createAPIFactory to $init() of PluginManager #8872

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 5 additions & 4 deletions packages/plugin-ext/src/hosted/browser/hosted-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ export class HostedPluginSupport {
if (!manager) {
const pluginId = getPluginId(hostContributions[0].plugin.metadata.model);
const rpc = this.initRpc(host, pluginId);
const apiStartfunction = setUpPluginApi(rpc, this.container);
this.mainPluginApiProviders.getContributions().forEach(p => p.initialize(rpc, this.container));
toDisconnect.push(rpc);

manager = rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT);
Expand Down Expand Up @@ -475,6 +477,8 @@ export class HostedPluginSupport {
},
jsonValidation
});
// now the ext services are fully set up
apiStartfunction();
if (toDisconnect.disposed) {
return undefined;
}
Expand All @@ -483,10 +487,7 @@ export class HostedPluginSupport {
}

protected initRpc(host: PluginHost, pluginId: string): RPCProtocol {
const rpc = host === 'frontend' ? new PluginWorker().rpc : this.createServerRpc(pluginId, host);
setUpPluginApi(rpc, this.container);
this.mainPluginApiProviders.getContributions().forEach(p => p.initialize(rpc, this.container));
return rpc;
return host === 'frontend' ? new PluginWorker().rpc : this.createServerRpc(pluginId, host);
}

private createServerRpc(pluginID: string, hostID: string): RPCProtocol {
Expand Down
42 changes: 4 additions & 38 deletions packages/plugin-ext/src/hosted/browser/worker/worker-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,13 @@
import { Emitter } from '@theia/core/lib/common/event';
import { RPCProtocolImpl } from '../../../common/rpc-protocol';
import { PluginManagerExtImpl } from '../../../plugin/plugin-manager';
import { MAIN_RPC_CONTEXT, Plugin, emptyPlugin, TerminalServiceExt } from '../../../common/plugin-api-rpc';
import { createAPIFactory } from '../../../plugin/plugin-context';
import { MAIN_RPC_CONTEXT, Plugin, emptyPlugin, PluginAPIFactory } from '../../../common/plugin-api-rpc';
import { getPluginId, PluginMetadata } from '../../../common/plugin-protocol';
import * as theia from '@theia/plugin';
import { PreferenceRegistryExtImpl } from '../../../plugin/preference-registry';
import { ExtPluginApi } from '../../../common/plugin-ext-api-contribution';
import { createDebugExtStub } from './debug-stub';
import { EditorsAndDocumentsExtImpl } from '../../../plugin/editors-and-documents';
import { WorkspaceExtImpl } from '../../../plugin/workspace';
import { MessageRegistryExt } from '../../../plugin/message-registry';
import { WorkerEnvExtImpl } from './worker-env-ext';
import { ClipboardExt } from '../../../plugin/clipboard-ext';
import { KeyValueStorageProxy } from '../../../plugin/plugin-storage';
import { WebviewsExtImpl } from '../../../plugin/webviews';
import { loadManifest } from './plugin-manifest-loader';
import { TerminalServiceExtImpl } from '../../../plugin/terminal-ext';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ctx = self as any;
Expand All @@ -55,15 +46,7 @@ function initialize(contextPath: string, pluginMetadata: PluginMetadata): void {
ctx.importScripts('/context/' + contextPath);
}
const envExt = new WorkerEnvExtImpl(rpc);
const storageProxy = new KeyValueStorageProxy(rpc);
const editorsAndDocuments = new EditorsAndDocumentsExtImpl(rpc);
const messageRegistryExt = new MessageRegistryExt(rpc);
const workspaceExt = new WorkspaceExtImpl(rpc, editorsAndDocuments, messageRegistryExt);
const preferenceRegistryExt = new PreferenceRegistryExtImpl(rpc, workspaceExt);
const debugExt = createDebugExtStub(rpc);
const clipboardExt = new ClipboardExt(rpc);
const webviewExt = new WebviewsExtImpl(rpc, workspaceExt);
const terminalService: TerminalServiceExt = new TerminalServiceExtImpl(rpc);

const pluginManager = new PluginManagerExtImpl({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -84,7 +67,7 @@ const pluginManager = new PluginManagerExtImpl({
return ctx[plugin.lifecycle.frontendModuleName];
}
},
async init(rawPluginData: PluginMetadata[]): Promise<[Plugin[], Plugin[]]> {
async init(apiFactory: PluginAPIFactory, rawPluginData: PluginMetadata[]): Promise<[Plugin[], Plugin[]]> {
const result: Plugin[] = [];
const foreign: Plugin[] = [];
// Process the plugins concurrently, making sure to keep the order.
Expand Down Expand Up @@ -148,20 +131,8 @@ const pluginManager = new PluginManagerExtImpl({
}
}
}
}, envExt, terminalService, storageProxy, preferenceRegistryExt, webviewExt, rpc);
}, envExt, debugExt, rpc);

const apiFactory = createAPIFactory(
rpc,
pluginManager,
envExt,
debugExt,
preferenceRegistryExt,
editorsAndDocuments,
workspaceExt,
messageRegistryExt,
clipboardExt,
webviewExt
);
let defaultApi: typeof theia;

const handler = {
Expand All @@ -174,7 +145,7 @@ const handler = {
}

if (!defaultApi) {
defaultApi = apiFactory(emptyPlugin);
defaultApi = pluginManager.apiFactory(emptyPlugin);
}

return defaultApi;
Expand All @@ -183,11 +154,6 @@ const handler = {
ctx['theia'] = new Proxy(Object.create(null), handler);

rpc.set(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT, pluginManager);
rpc.set(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT, editorsAndDocuments);
rpc.set(MAIN_RPC_CONTEXT.WORKSPACE_EXT, workspaceExt);
rpc.set(MAIN_RPC_CONTEXT.PREFERENCE_REGISTRY_EXT, preferenceRegistryExt);
rpc.set(MAIN_RPC_CONTEXT.STORAGE_EXT, storageProxy);
rpc.set(MAIN_RPC_CONTEXT.WEBVIEWS_EXT, webviewExt);

function isElectron(): boolean {
if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) {
Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-ext/src/hosted/node/hosted-plugin-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ export class HostedPluginProcess implements ServerPluginRunner {
this.childProcess.on('message', message => {
if (this.client) {
this.client.postMessage(message);
} else {
this.logger.error('Dropping message: ' + JSON.stringify(message));
}
});
}
Expand Down
66 changes: 13 additions & 53 deletions packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,87 +17,47 @@
import { PluginManagerExtImpl } from '../../plugin/plugin-manager';
import { MAIN_RPC_CONTEXT, Plugin, PluginAPIFactory } from '../../common/plugin-api-rpc';
import { PluginMetadata } from '../../common/plugin-protocol';
import { createAPIFactory } from '../../plugin/plugin-context';
import { EnvExtImpl } from '../../plugin/env';
import { PreferenceRegistryExtImpl } from '../../plugin/preference-registry';
import { loadManifest } from './plugin-manifest-loader';
import { ExtPluginApi } from '../../common/plugin-ext-api-contribution';
import { DebugExtImpl } from '../../plugin/node/debug/debug';
import { EditorsAndDocumentsExtImpl } from '../../plugin/editors-and-documents';
import { WorkspaceExtImpl } from '../../plugin/workspace';
import { MessageRegistryExt } from '../../plugin/message-registry';
import { EnvNodeExtImpl } from '../../plugin/node/env-node-ext';
import { ClipboardExt } from '../../plugin/clipboard-ext';
import { loadManifest } from './plugin-manifest-loader';
import { KeyValueStorageProxy } from '../../plugin/plugin-storage';
import { WebviewsExtImpl } from '../../plugin/webviews';
import { TerminalServiceExtImpl } from '../../plugin/terminal-ext';
import { DebugExtImpl } from '../../plugin/node/debug/debug';

/**
* Handle the RPC calls.
*/
export class PluginHostRPC {

private apiFactory: PluginAPIFactory;

private pluginManager: PluginManagerExtImpl;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(protected readonly rpc: any) {
}

initialize(): void {
const envExt = new EnvNodeExtImpl(this.rpc);
const storageProxy = new KeyValueStorageProxy(this.rpc);
const debugExt = new DebugExtImpl(this.rpc);
const editorsAndDocumentsExt = new EditorsAndDocumentsExtImpl(this.rpc);
const messageRegistryExt = new MessageRegistryExt(this.rpc);
const workspaceExt = new WorkspaceExtImpl(this.rpc, editorsAndDocumentsExt, messageRegistryExt);
const preferenceRegistryExt = new PreferenceRegistryExtImpl(this.rpc, workspaceExt);
const clipboardExt = new ClipboardExt(this.rpc);
const webviewExt = new WebviewsExtImpl(this.rpc, workspaceExt);
const terminalService = new TerminalServiceExtImpl(this.rpc);
this.pluginManager = this.createPluginManager(envExt, terminalService, storageProxy, preferenceRegistryExt, webviewExt, this.rpc);
this.pluginManager = this.createPluginManager(this.rpc);
this.rpc.set(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT, this.pluginManager);
this.rpc.set(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT, editorsAndDocumentsExt);
this.rpc.set(MAIN_RPC_CONTEXT.WORKSPACE_EXT, workspaceExt);
this.rpc.set(MAIN_RPC_CONTEXT.PREFERENCE_REGISTRY_EXT, preferenceRegistryExt);
this.rpc.set(MAIN_RPC_CONTEXT.STORAGE_EXT, storageProxy);
this.rpc.set(MAIN_RPC_CONTEXT.WEBVIEWS_EXT, webviewExt);

this.apiFactory = createAPIFactory(
this.rpc,
this.pluginManager,
envExt,
debugExt,
preferenceRegistryExt,
editorsAndDocumentsExt,
workspaceExt,
messageRegistryExt,
clipboardExt,
webviewExt
);
}

async terminate(): Promise<void> {
await this.pluginManager.terminate();
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
initContext(contextPath: string, plugin: Plugin): any {
initContext(apiFactory: PluginAPIFactory, contextPath: string, plugin: Plugin): any {
const { name, version } = plugin.rawModel;
console.log('PLUGIN_HOST(' + process.pid + '): initializing(' + name + '@' + version + ' with ' + contextPath + ')');
try {
const backendInit = require(contextPath);
backendInit.doInitialization(this.apiFactory, plugin);
backendInit.doInitialization(apiFactory, plugin);
} catch (e) {
console.error(e);
}
}

createPluginManager(
envExt: EnvExtImpl, terminalService: TerminalServiceExtImpl, storageProxy: KeyValueStorageProxy, preferencesManager: PreferenceRegistryExtImpl, webview: WebviewsExtImpl,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rpc: any): PluginManagerExtImpl {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
createPluginManager(rpc: any): PluginManagerExtImpl {
const envExt = new EnvNodeExtImpl(this.rpc);
const debugExt = new DebugExtImpl(this.rpc);

const { extensionTestsPath } = process.env;
const self = this;
const pluginManager = new PluginManagerExtImpl({
Expand Down Expand Up @@ -143,7 +103,7 @@ export class PluginHostRPC {
return require(plugin.pluginPath);
}
},
async init(raw: PluginMetadata[]): Promise<[Plugin[], Plugin[]]> {
async init(apiFactory: PluginAPIFactory, raw: PluginMetadata[]): Promise<[Plugin[], Plugin[]]> {
console.log('PLUGIN_HOST(' + process.pid + '): PluginManagerExtImpl/init()');
const result: Plugin[] = [];
const foreign: Plugin[] = [];
Expand Down Expand Up @@ -177,7 +137,7 @@ export class PluginHostRPC {
rawModel
};

self.initContext(backendInitPath, plugin);
self.initContext(apiFactory, backendInitPath, plugin);

result.push(plugin);
}
Expand Down Expand Up @@ -227,7 +187,7 @@ export class PluginHostRPC {
`Path ${extensionTestsPath} does not point to a valid extension test runner.`
);
} : undefined
}, envExt, terminalService, storageProxy, preferencesManager, webview, rpc);
}, envExt, debugExt, rpc);
return pluginManager;
}
}
10 changes: 6 additions & 4 deletions packages/plugin-ext/src/main/browser/main-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import { TimelineMainImpl } from './timeline-main';
import { AuthenticationMainImpl } from './authentication-main';
import { ThemingMainImpl } from './theming-main';

export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container): void {
export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container): () => void {
const authenticationMain = new AuthenticationMainImpl(rpc, container);
rpc.set(PLUGIN_RPC_CONTEXT.AUTHENTICATION_MAIN, authenticationMain);

Expand Down Expand Up @@ -92,9 +92,6 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
const editorsMain = new TextEditorsMainImpl(editorsAndDocuments, rpc, bulkEditService, monacoEditorService);
rpc.set(PLUGIN_RPC_CONTEXT.TEXT_EDITORS_MAIN, editorsMain);

// start listening only after all clients are subscribed to events
editorsAndDocuments.listen();

const statusBarMessageRegistryMain = new StatusBarMessageRegistryMainImpl(container);
rpc.set(PLUGIN_RPC_CONTEXT.STATUS_BAR_MESSAGE_REGISTRY_MAIN, statusBarMessageRegistryMain);

Expand Down Expand Up @@ -163,4 +160,9 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container

const themingMain = new ThemingMainImpl(rpc);
rpc.set(PLUGIN_RPC_CONTEXT.THEMING_MAIN, themingMain);

return () => {
// start listening only after all clients are subscribed to events
editorsAndDocuments.listen();
};
}
5 changes: 2 additions & 3 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ export function createAPIFactory(
workspaceExt: WorkspaceExtImpl,
messageRegistryExt: MessageRegistryExt,
clipboard: ClipboardExt,
webviewExt: WebviewsExtImpl
webviewExt: WebviewsExtImpl,
terminalExt: TerminalServiceExtImpl
): PluginAPIFactory {

const authenticationExt = rpc.set(MAIN_RPC_CONTEXT.AUTHENTICATION_EXT, new AuthenticationExtImpl(rpc));
Expand All @@ -187,7 +188,6 @@ export function createAPIFactory(
const editors = rpc.set(MAIN_RPC_CONTEXT.TEXT_EDITORS_EXT, new TextEditorsExtImpl(rpc, editorsAndDocumentsExt));
const documents = rpc.set(MAIN_RPC_CONTEXT.DOCUMENTS_EXT, new DocumentsExtImpl(rpc, editorsAndDocumentsExt));
const statusBarMessageRegistryExt = new StatusBarMessageRegistryExt(rpc);
const terminalExt = rpc.set(MAIN_RPC_CONTEXT.TERMINAL_EXT, new TerminalServiceExtImpl(rpc));
const outputChannelRegistryExt = rpc.set(MAIN_RPC_CONTEXT.OUTPUT_CHANNEL_REGISTRY_EXT, new OutputChannelRegistryExtImpl(rpc));
const languagesExt = rpc.set(MAIN_RPC_CONTEXT.LANGUAGES_EXT, new LanguagesExtImpl(rpc, documents, commandRegistry));
const treeViewsExt = rpc.set(MAIN_RPC_CONTEXT.TREE_VIEWS_EXT, new TreeViewsExtImpl(rpc, commandRegistry));
Expand All @@ -200,7 +200,6 @@ export function createAPIFactory(
const labelServiceExt = rpc.set(MAIN_RPC_CONTEXT.LABEL_SERVICE_EXT, new LabelServiceExtImpl(rpc));
const timelineExt = rpc.set(MAIN_RPC_CONTEXT.TIMELINE_EXT, new TimelineExtImpl(rpc, commandRegistry));
const themingExt = rpc.set(MAIN_RPC_CONTEXT.THEMING_EXT, new ThemingExtImpl(rpc));
rpc.set(MAIN_RPC_CONTEXT.DEBUG_EXT, debugExt);

return function (plugin: InternalPlugin): typeof theia {
const authentication: typeof theia.authentication = {
Expand Down
Loading