Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Commit

Permalink
Handle the changes introduced by upstream theia with allowing multipl…
Browse files Browse the repository at this point in the history
…e clients on plug-ins
  • Loading branch information
benoitf committed Mar 14, 2019
1 parent 58a59ba commit 6016e3a
Show file tree
Hide file tree
Showing 8 changed files with 876 additions and 2,224 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ export class HostedPluginRemote {
this.setupWebsocket();
}

public clientClosed(): void {

Array.from(this.endpointsSockets.values()).forEach(websocket => {
websocket.send(JSON.stringify({
'internal': {
'method': 'stop'
}
}));
websocket.close();
});
}

/**
* Called when a client is connecting to this endpoint
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ import { ServerPluginProxyRunner } from './server-plugin-proxy-runner';
import { MetadataProcessor, ServerPluginRunner } from '@theia/plugin-ext/lib/common';
import { RemoteMetadataProcessor } from './remote-metadata-processor';
import { HostedPluginMapping } from './plugin-remote-mapping';
import { ConnectionContainerModule } from '@theia/core/lib/node/messaging/connection-container-module';

export default new ContainerModule(bind => {
bind(HostedPluginMapping).toSelf().inSingletonScope();
const localModule = ConnectionContainerModule.create(({ bind }) => {
bind(HostedPluginRemote).toSelf().inSingletonScope();
bind(ServerPluginRunner).to(ServerPluginProxyRunner).inSingletonScope();
});

export default new ContainerModule(bind => {
bind(HostedPluginMapping).toSelf().inSingletonScope();
bind(MetadataProcessor).to(RemoteMetadataProcessor).inSingletonScope();
bind(ConnectionContainerModule).toConstantValue(localModule);
}
);
67 changes: 46 additions & 21 deletions dockerfiles/theia-endpoint-runtime/src/node/plugin-remote-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { HostedPluginReader } from '@theia/plugin-ext/lib/hosted/node/plugin-rea
import pluginExtBackendModule from '@theia/plugin-ext/lib/plugin-ext-backend-module';
import { Container, inject, injectable } from 'inversify';
import { DummyTraceLogger } from './dummy-trace-logger';
import { HostedPluginRemote } from './hosted-plugin-remote';
import pluginRemoteBackendModule from './plugin-remote-backend-module';
import { TerminalContainerAware } from './terminal-container-aware';
import { PluginDiscovery } from './plugin-discovery';
Expand Down Expand Up @@ -80,14 +79,12 @@ export class PluginRemoteInit {
inversifyContainer.load(pluginVscodeBackendModule);

// override handler to our own class
inversifyContainer.rebind(PluginDeployerHandler).to(PluginDeployerHandlerImpl).inSingletonScope();
inversifyContainer.bind(PluginDeployerHandlerImpl).toSelf().inSingletonScope();
inversifyContainer.rebind(PluginDeployerHandler).toService(PluginDeployerHandlerImpl);

// bind local stuff
inversifyContainer.load(pluginRemoteBackendModule);

// remove endpoint
inversifyContainer.unbind(HostedPluginRemote);

inversifyContainer.bind<number>('plugin.port').toConstantValue(this.pluginPort);

// start the deployer
Expand Down Expand Up @@ -160,9 +157,8 @@ to pick-up automatically a free port`));

// create a new client on top of socket
newClient(id: number, socket: ws): WebSocketClient {
const webSocketClient = new WebSocketClient(id, socket);
const emitter = new Emitter();
webSocketClient.emitter = emitter;
const webSocketClient = new WebSocketClient(id, socket, emitter);
webSocketClient.rpc = new RPCProtocolImpl({
onMessage: emitter.event,
// send messages to this client
Expand All @@ -173,6 +169,7 @@ to pick-up automatically a free port`));

const pluginHostRPC = new PluginHostRPC(webSocketClient.rpc);
pluginHostRPC.initialize();
webSocketClient.pluginHostRPC = pluginHostRPC;

// override window.createTerminal to be container aware
// tslint:disable-next-line:no-any
Expand All @@ -192,14 +189,29 @@ to pick-up automatically a free port`));
});

socket.on('close', (code, reason) => {
webSocketClients.clear();
webSocketClients.delete(channelId);
});

socket.on('message', (data: ws.Data) => {
socket.on('message', async (data: ws.Data) => {
const jsonParsed = JSON.parse(data.toString());

// handle local call
if (jsonParsed.internal) {

// asked to stop plug-ins
if (jsonParsed.internal.method && jsonParsed.internal.method === 'stop') {
try {
// wait to stop plug-ins
await client.pluginHostRPC.stopContext();

// ok now we can dispose the emitter
client.disposeEmitter();
} catch (e) {
console.error(e);
}
return;
}

// asked to grab metadata, send them
if (jsonParsed.internal.metadata && 'request' === jsonParsed.internal.metadata) {
// apply host on all local metadata
Expand All @@ -218,14 +230,9 @@ to pick-up automatically a free port`));
return;
}

for (const webSocketClient of webSocketClients.values()) {
// send what is inside the message (wrapped message)
try {
webSocketClient.emitter.fire(jsonParsed);
} catch (e) {
console.error(e);
}
}
// send what is inside the message (wrapped message)
client.fire(jsonParsed);

});
}
}
Expand All @@ -236,10 +243,11 @@ to pick-up automatically a free port`));
class WebSocketClient {

public rpc: RPCProtocolImpl;
// tslint:disable-next-line:no-any
public emitter: Emitter<any>;

constructor(private readonly id: number, private socket: ws) {
public pluginHostRPC: PluginHostRPC;

// tslint:disable-next-line:no-any
constructor(private readonly id: number, private socket: ws, private readonly emitter: Emitter<any>) {
}

public getIdentifier(): number {
Expand All @@ -249,7 +257,24 @@ class WebSocketClient {
// message is a JSON entry
// tslint:disable-next-line:no-any
send(message: any) {
this.socket.send(JSON.stringify(message));
try {
this.socket.send(JSON.stringify(message));
} catch (error) {
console.log('error socket while sending', error, message);
}
}

disposeEmitter(): void {
this.emitter.dispose();
}

// tslint:disable-next-line:no-any
fire(message: any) {
try {
this.emitter.fire(message);
} catch (error) {
console.log('error socket while sending', error, message);
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export class ServerPluginProxyRunner implements ServerPluginRunner {
this.hostedPluginRemote.setClient(client);
}

public clientClosed(): void {
this.hostedPluginRemote.clientClosed();
}

// tslint:disable-next-line:no-any
public acceptMessage(jsonMessage: any): boolean {
return jsonMessage.pluginID !== undefined;
Expand Down
6 changes: 6 additions & 0 deletions dockerfiles/theia-endpoint-runtime/src/node/websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,10 @@ export class Websocket {
private onError(e: Error) { }
private onClose(reason: string) { }

/***
* Closing websocket with proper error code.
*/
public close(): void {
this.instance.close(1000);
}
}
Loading

0 comments on commit 6016e3a

Please sign in to comment.