Skip to content

Commit

Permalink
RPC Protocol ClientProxyHandler Init Events #13172
Browse files Browse the repository at this point in the history
* automate init by specifying required remote depednencies on set
  • Loading branch information
jfaltermeier committed Dec 18, 2023
1 parent cfcfc68 commit 14e6270
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 32 deletions.
39 changes: 22 additions & 17 deletions packages/plugin-ext/src/common/rpc-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,7 @@ export interface RPCProtocol extends Disposable {
/**
* Register manually created instance.
*/
set<T, R extends T>(identifier: ProxyIdentifier<T>, instance: R): R;

/**
* Sent when a proxy handler is initialized.
*/
onInitialize: Event<string>;

/**
* Makes sure that the proxy is eagerly initialized.
*/
initialize<T>(proxyId: ProxyIdentifier<T>): void;
set<T, R extends T>(identifier: ProxyIdentifier<T>, instance: R, remoteDependencies?: Set<ProxyIdentifier<T>>): R;

}

Expand Down Expand Up @@ -91,6 +81,7 @@ export class RPCProtocolImpl implements RPCProtocol {
private readonly locals = new Map<string, RpcInvocationHandler>();
private readonly proxies = new Map<string, any>();
private readonly handler = new Map<string, any>();
private readonly remoteDependencies = new Map<string, Set<ProxyIdentifier<any>>>();
private readonly multiplexer: ChannelMultiplexer;
private readonly encoder = new MsgPackMessageEncoder();
private readonly decoder = new MsgPackMessageDecoder();
Expand All @@ -104,6 +95,7 @@ export class RPCProtocolImpl implements RPCProtocol {
this.toDispose.push(this.multiplexer = new ChannelMultiplexer(new BatchingChannel(channel)));
this.toDispose.push(Disposable.create(() => this.proxies.clear()));
this.toDispose.push(Disposable.create(() => this.handler.clear()));
this.toDispose.push(Disposable.create(() => this.remoteDependencies.clear()));
this.toDispose.push(this.onInitializeEmitter);
}

Expand Down Expand Up @@ -131,13 +123,20 @@ export class RPCProtocolImpl implements RPCProtocol {
const handler = new ClientProxyHandler({
id: proxyId, encoder: this.encoder, decoder: this.decoder,
channelProvider: () => this.multiplexer.open(proxyId),
onInitialize: () => this.onInitializeEmitter.fire(proxyId),
onInitialize: () => {
const dependencies = this.remoteDependencies.get(proxyId);
if (dependencies) {
dependencies.forEach(dep => {
this.initialize(dep);
});
}
},
});
this.handler.set(proxyId, handler);
return new Proxy(Object.create(null), handler);
}

set<T, R extends T>(identifier: ProxyIdentifier<T>, instance: R): R {
set<T, R extends T>(identifier: ProxyIdentifier<T>, instance: R, remoteDependencies: Set<ProxyIdentifier<T>> = new Set()): R {
if (this.isDisposed) {
throw ConnectionClosedError.create();
}
Expand All @@ -161,16 +160,22 @@ export class RPCProtocolImpl implements RPCProtocol {
if (Disposable.is(instance)) {
this.toDispose.push(instance);
}

this.toDispose.push(Disposable.create(() => this.locals.delete(identifier.id)));

for (const remoteDep of remoteDependencies) {
const deps = new Set(remoteDependencies);
deps.delete(remoteDep);
if (!this.remoteDependencies.has(remoteDep.id)) {
this.remoteDependencies.set(remoteDep.id, new Set());
}
deps.forEach(dep => this.remoteDependencies.get(remoteDep.id)?.add(dep));
}

}
return instance;
}

get onInitialize(): Event<string> {
return this.onInitializeEmitter.event;
};

initialize<T>(proxyId: ProxyIdentifier<T>): void {
/* make sure proxy exists */
this.getProxy(proxyId);
Expand Down
5 changes: 0 additions & 5 deletions packages/plugin-ext/src/main/browser/documents-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,6 @@ export class DocumentsMainImpl implements DocumentsMain, Disposable {
private untitledResourceResolver: UntitledResourceResolver,
private languageService: MonacoLanguages,
) {
rpc.onInitialize(proxyId => {
if (proxyId === MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT.id) {
rpc.initialize(MAIN_RPC_CONTEXT.DOCUMENTS_EXT);
}
});
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.DOCUMENTS_EXT);

this.toDispose.push(editorsAndDocuments);
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/main/browser/main-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
const untitledResourceResolver = container.get(UntitledResourceResolver);
const languageService = container.get(MonacoLanguages);
const documentsMain = new DocumentsMainImpl(editorsAndDocuments, modelService, rpc, editorManager, openerService, shell, untitledResourceResolver, languageService);
rpc.set(PLUGIN_RPC_CONTEXT.DOCUMENTS_MAIN, documentsMain);
rpc.set(PLUGIN_RPC_CONTEXT.DOCUMENTS_MAIN, documentsMain, new Set([MAIN_RPC_CONTEXT.DOCUMENTS_EXT, MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT]));

const notebookService = container.get(NotebookService);
const pluginSupport = container.get(HostedPluginSupport);
Expand Down
9 changes: 0 additions & 9 deletions packages/plugin-ext/src/plugin/node/debug/debug.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@ import * as chai from 'chai';
import { ProxyIdentifier, RPCProtocol } from '../../../common/rpc-protocol';

import { DebugExtImpl } from '../../debug/debug-ext';
import { Emitter, Event } from '@theia/core';

const expect = chai.expect;

describe('Debug API', () => {

describe('#asDebugSourceURI', () => {

const mockEmitter = new Emitter<string>();

const mockRPCProtocol: RPCProtocol = {
getProxy<T>(_proxyId: ProxyIdentifier<T>): T {
return {} as T;
Expand All @@ -38,12 +35,6 @@ describe('Debug API', () => {
dispose(): void {
// Nothing
},
get onInitialize(): Event<string> {
return mockEmitter.event;
},
initialize<T>(_proxyId: ProxyIdentifier<T>): void {
// Nothing
}
};

const debug = new DebugExtImpl(mockRPCProtocol);
Expand Down

0 comments on commit 14e6270

Please sign in to comment.