Skip to content

Commit

Permalink
Support for "--headless-hosted-plugin-inspect" cmd argument (#13918)
Browse files Browse the repository at this point in the history
* introduce getServerName method on backend 
* add preferences to specify node js debug ports per hosted plugin server
* adjust PluginDebugConfiguration to also accept and array of server-name to debug port entries
  • Loading branch information
jfaltermeier committed Aug 5, 2024
1 parent 291bc0e commit effb3ec
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ export class HostedPluginManagerClient {
try {
if (this.isDebug) {
this.pluginInstanceURL = await this.hostedPluginServer.runDebugHostedPluginInstance(this.pluginLocation!.toString(), {
debugMode: this.hostedPluginPreferences['hosted-plugin.debugMode']
debugMode: this.hostedPluginPreferences['hosted-plugin.debugMode'],
debugPort: [...this.hostedPluginPreferences['hosted-plugin.debugPorts']]
});
await this.startDebugSessionManager();
} else {
Expand Down Expand Up @@ -372,6 +373,9 @@ export class HostedPluginManagerClient {
if (config.pluginLocation) {
this.pluginLocation = new URI((!config.pluginLocation.startsWith('/') ? '/' : '') + config.pluginLocation.replace(/\\/g, '/')).withScheme('file');
}
if (config.debugPort === undefined) {
config.debugPort = [...this.hostedPluginPreferences['hosted-plugin.debugPorts']];
}
return config;
}

Expand Down
24 changes: 24 additions & 0 deletions packages/plugin-dev/src/browser/hosted-plugin-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import { interfaces } from '@theia/core/shared/inversify';
import { createPreferenceProxy, PreferenceProxy, PreferenceService, PreferenceContribution, PreferenceSchema } from '@theia/core/lib/browser';
import { nls } from '@theia/core/lib/common/nls';
import { PluginDebugPort } from '../common';

export const HostedPluginConfigSchema: PreferenceSchema = {
'type': 'object',
Expand All @@ -42,6 +43,28 @@ export const HostedPluginConfigSchema: PreferenceSchema = {
'Array of glob patterns for locating generated JavaScript files (`${pluginPath}` will be replaced by plugin actual path).'
),
default: ['${pluginPath}/out/**/*.js']
},
'hosted-plugin.debugPorts': {
type: 'array',
items: {
type: 'object',
properties: {
'serverName': {
type: 'string',
description: nls.localize('theia/plugin-dev/debugPorts/serverName',
'The plugin host server name, e.g. "hosted-plugin" as in "--hosted-plugin-inspect=" ' +
'or "headless-hosted-plugin" as in "--headless-hosted-plugin-inspect="'),
},
'debugPort': {
type: 'number',
minimum: 0,
maximum: 65535,
description: nls.localize('theia/plugin-dev/debugPorts/debugPort', 'Port to use for this server\'s Node.js debug'),
}
},
},
default: undefined,
description: nls.localize('theia/plugin-dev/debugPorts', 'Port configuration per server for Node.js debug'),
}
}
};
Expand All @@ -50,6 +73,7 @@ export interface HostedPluginConfiguration {
'hosted-plugin.watchMode': boolean;
'hosted-plugin.debugMode': string;
'hosted-plugin.launchOutFiles': string[];
'hosted-plugin.debugPorts': PluginDebugPort[];
}

export const HostedPluginPreferenceContribution = Symbol('HostedPluginPreferenceContribution');
Expand Down
7 changes: 6 additions & 1 deletion packages/plugin-dev/src/common/plugin-dev-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@ export interface PluginDevServer extends RpcServer<PluginDevClient> {
export interface PluginDevClient {
}

export interface PluginDebugPort {
serverName: string,
debugPort: number,
}

export interface PluginDebugConfiguration {
debugMode?: string;
pluginLocation?: string;
debugPort?: string;
debugPort?: string | PluginDebugPort[]
}
15 changes: 14 additions & 1 deletion packages/plugin-dev/src/node/hosted-instance-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,20 @@ export abstract class AbstractHostedInstanceManager implements HostedInstanceMan
}

if (debugConfig) {
command.push(`--hosted-plugin-${debugConfig.debugMode || 'inspect'}=0.0.0.0${debugConfig.debugPort ? ':' + debugConfig.debugPort : ''}`);
if (debugConfig.debugPort === undefined) {
command.push(`--hosted-plugin-${debugConfig.debugMode || 'inspect'}=0.0.0.0`);
} else if (typeof debugConfig.debugPort === 'string') {
command.push(`--hosted-plugin-${debugConfig.debugMode || 'inspect'}=0.0.0.0:${debugConfig.debugPort}`);
} else if (Array.isArray(debugConfig.debugPort)) {
if (debugConfig.debugPort.length === 0) {
// treat empty array just like undefined
command.push(`--hosted-plugin-${debugConfig.debugMode || 'inspect'}=0.0.0.0`);
} else {
for (const serverToPort of debugConfig.debugPort) {
command.push(`--${serverToPort.serverName}-${debugConfig.debugMode || 'inspect'}=0.0.0.0:${serverToPort.debugPort}`);
}
}
}
}
return command;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// *****************************************************************************
// Copyright (C) 2024 EclipseSource and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { injectable } from '@theia/core/shared/inversify';
import { HostedPluginServerImpl } from '@theia/plugin-ext/lib/hosted/node/plugin-service';

@injectable()
export class HeadlessHostedPluginServerImpl extends HostedPluginServerImpl {
protected override getServerName(): string {
return 'headless-hosted-plugin';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import { ContainerModule, interfaces } from '@theia/core/shared/inversify';
import { ExtPluginApiProvider, HostedPluginServer, PluginHostEnvironmentVariable, PluginScanner } from '@theia/plugin-ext';
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin';
import { HostedPluginProcess, HostedPluginProcessConfiguration } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin-process';
import { BackendPluginHostableFilter, HostedPluginServerImpl } from '@theia/plugin-ext/lib/hosted/node/plugin-service';
import { BackendPluginHostableFilter } from '@theia/plugin-ext/lib/hosted/node/plugin-service';
import { MaybePromise } from '@theia/core';
import { HeadlessPluginContainerModule } from '../../common/headless-plugin-container';
import { HeadlessHostedPluginSupport, isHeadlessPlugin } from './headless-hosted-plugin';
import { TheiaHeadlessPluginScanner } from './scanners/scanner-theia-headless';
import { SupportedHeadlessActivationEvents } from '../../common/headless-plugin-protocol';
import { HeadlessHostedPluginServerImpl } from './headless-plugin-service';

export function bindCommonHostedBackend(bind: interfaces.Bind): void {
bind(HostedPluginProcess).toSelf().inSingletonScope();
Expand All @@ -36,8 +37,8 @@ export function bindCommonHostedBackend(bind: interfaces.Bind): void {
bindContributionProvider(bind, PluginHostEnvironmentVariable);
bindContributionProvider(bind, SupportedHeadlessActivationEvents);

bind(HostedPluginServerImpl).toSelf().inSingletonScope();
bind(HostedPluginServer).toService(HostedPluginServerImpl);
bind(HeadlessHostedPluginServerImpl).toSelf().inSingletonScope();
bind(HostedPluginServer).toService(HeadlessHostedPluginServerImpl);
bind(HeadlessHostedPluginSupport).toSelf().inSingletonScope();
bind(BackendPluginHostableFilter).toConstantValue(isHeadlessPlugin);

Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-ext/src/hosted/node/hosted-plugin-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ export class HostedPluginProcess implements ServerPluginRunner {
}
}

public runPluginServer(): void {
public runPluginServer(serverName?: string): void {
if (this.childProcess) {
this.terminatePluginServer();
}
this.terminatingPluginServer = false;
this.childProcess = this.fork({
serverName: 'hosted-plugin',
serverName: serverName ?? 'hosted-plugin',
logger: this.logger,
args: []
});
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-ext/src/hosted/node/hosted-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ export class HostedPluginSupport {
}
}

runPluginServer(): void {
runPluginServer(serverName?: string): void {
if (!this.isPluginProcessRunning) {
this.hostedPluginProcess.runPluginServer();
this.hostedPluginProcess.runPluginServer(serverName);
this.isPluginProcessRunning = true;
}
}
Expand Down
7 changes: 6 additions & 1 deletion packages/plugin-ext/src/hosted/node/plugin-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class HostedPluginServerImpl implements HostedPluginServer {
protected toDispose = new DisposableCollection();

protected _ignoredPlugins?: Set<PluginIdentifiers.VersionedId>;

// We ignore any plugins that are marked as uninstalled the first time the frontend requests information about deployed plugins.
protected get ignoredPlugins(): Set<PluginIdentifiers.VersionedId> {
if (!this._ignoredPlugins) {
Expand Down Expand Up @@ -96,6 +97,10 @@ export class HostedPluginServerImpl implements HostedPluginServer {
]);
}

protected getServerName(): string {
return 'hosted-plugin';
}

dispose(): void {
this.toDispose.dispose();
}
Expand All @@ -109,7 +114,7 @@ export class HostedPluginServerImpl implements HostedPluginServer {
const backendPlugins = (await this.deployerHandler.getDeployedBackendPlugins())
.filter(this.backendPluginHostableFilter);
if (backendPlugins.length > 0) {
this.hostedPlugin.runPluginServer();
this.hostedPlugin.runPluginServer(this.getServerName());
}
const plugins = new Set<PluginIdentifiers.VersionedId>();
const addIds = async (identifiers: PluginIdentifiers.VersionedId[]): Promise<void> => {
Expand Down

0 comments on commit effb3ec

Please sign in to comment.