Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
56 changes: 56 additions & 0 deletions packages/extension/src/common/ext.process.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { SumiApiExtenders } from './sumi';
import type { CommandHandler } from './vscode';
import type { ConstructorOf, Injector } from '@opensumi/di';
import type { ILogService, LogLevel } from '@opensumi/ide-core-common';
import type Stream from 'stream';

export interface IBuiltInCommand {
id: string;
handler: CommandHandler;
}

export interface CustomChildProcess {
stdin: Stream.Writable;
stdout: Stream.Readable;
kill: () => void;
}

export interface CustomChildProcessModule {
spawn(command: string, args: string | string[], options: any): CustomChildProcess;
}

export const ExtHostAppConfig = Symbol('ExtHostAppConfig');
export interface ExtHostAppConfig {
/**
* exthost log service class
*/
LogServiceClass?: ConstructorOf<ILogService>;
/**
* 插件日志自定义实现路径
*/
extLogServiceClassPath?: string;
logDir?: string;
logLevel?: LogLevel;
builtinCommands?: IBuiltInCommand[];
customDebugChildProcess?: CustomChildProcessModule;
/**
* 集成方自定义 vscode.version 版本
* 设置该参数可能会导致插件运行异常
* @type {string} 插件版本号
* @memberof ExtHostAppConfig
*/
customVSCodeEngineVersion?: string;
/**
* control rpcProtocol message timeout
* default -1,it means disable
*/
rpcMessageTimeout?: number;
/**
* register external sumi extension api
*/
sumiApiExtenders?: SumiApiExtenders;
}

export interface ExtProcessConfig extends ExtHostAppConfig {
injector?: Injector;
}
27 changes: 26 additions & 1 deletion packages/extension/src/common/sumi/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { createExtHostContextProxyIdentifier, createMainContextProxyIdentifier } from '@opensumi/ide-connection';
import {
IRPCProtocol,
ProxyIdentifier,
createExtHostContextProxyIdentifier,
createMainContextProxyIdentifier,
} from '@opensumi/ide-connection';

import { IExtHostChatAgents, IMainThreadChatAgents } from './chat-agents';
import { IExtHostCommon, IMainThreadCommon } from './common';
Expand Down Expand Up @@ -27,3 +32,23 @@ export const ExtHostSumiAPIIdentifier = {
ExtHostIDEWindow: createExtHostContextProxyIdentifier<IExtHostIDEWindow>('ExtHostIDEWindow'),
ExtHostChatAgents: createExtHostContextProxyIdentifier<IExtHostChatAgents>('ExtHostChatAgents'),
};

/**
* sumi API extender
*/
export abstract class SumiApiExtender<T = any> {
constructor(protected rpcProtocol: IRPCProtocol) {}
/**
* create rpc service when main thread could call
*/
createRPCService?: () => [identifier: ProxyIdentifier<T>, service: T];
/**
* api factory
* can use rpc service to call main thread
*/
createApiFactory: (service?: T) => any;
}

export interface SumiApiExtenders extends Record<string, any> {
[api: string]: new (rpcProtocol: IRPCProtocol) => SumiApiExtender;
}
20 changes: 18 additions & 2 deletions packages/extension/src/hosted/api/sumi/ext.host.api.impl.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { IRPCProtocol } from '@opensumi/ide-connection';
import { IReporter, REPORT_HOST, ReporterService } from '@opensumi/ide-core-common';
import { IReporter, REPORT_HOST, ReporterService, isFunction } from '@opensumi/ide-core-common';

import { IExtensionHostService, IExtensionWorkerHost, WorkerHostAPIIdentifier } from '../../../common';
import { ExtHostSumiAPIIdentifier } from '../../../common/sumi';
import { ExtHostSumiAPIIdentifier, SumiApiExtenders } from '../../../common/sumi';
import { ExtHostAPIIdentifier, IExtensionDescription } from '../../../common/vscode';
import { ExtensionHostEditorService } from '../vscode/editor/editor.host';

Expand All @@ -21,6 +21,7 @@ export function createAPIFactory(
extensionService: IExtensionHostService | IExtensionWorkerHost,
type: string,
reporterEmitter: IReporter,
sumiApiExtenders: SumiApiExtenders = {},
) {
if (type === 'worker') {
rpcProtocol.set(WorkerHostAPIIdentifier.ExtWorkerHostExtensionService, extensionService);
Expand Down Expand Up @@ -58,6 +59,20 @@ export function createAPIFactory(
new ExtHostChatAgents(rpcProtocol),
) as ExtHostChatAgents;

const externalSumiApis = Object.keys(sumiApiExtenders).reduce((acc, key) => {
const SumiApiExtender = sumiApiExtenders[key];
const extender = new SumiApiExtender(rpcProtocol);
let rpcService;
// register external api rpc protocol
if (isFunction(extender.createRPCService)) {
const [identifier, service] = extender.createRPCService();
rpcService = service;
rpcProtocol.set(identifier, service);
}
acc[key] = extender.createApiFactory(rpcService);
return acc;
}, {});

return (extension: IExtensionDescription) => {
const reporter = new ReporterService(reporterEmitter, {
extensionId: extension.extensionId,
Expand All @@ -75,6 +90,7 @@ export function createAPIFactory(
commands: createCommandsApiFactory(extHostCommands, extHostEditors, extension),
toolbar: createToolbarAPIFactory(extension, extHostToolbar),
chat: createChatApiFactory(extension, extHostChatAgents),
...externalSumiApis,
};
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
IDebuggerContribution,
} from '@opensumi/ide-debug';

import { CustomChildProcessModule } from '../../../../common/ext.process';
import {
IExtHostCommands,
IExtHostDebugService,
Expand All @@ -25,7 +26,6 @@ import {
Uri,
} from '../../../../common/vscode/ext-types';
import { Breakpoint } from '../../../../common/vscode/models';
import { CustomChildProcessModule } from '../../../ext.process-base';

import { IDebugConfigurationProvider } from './common';
import { resolveDebugAdapterExecutable } from './extension-debug-adapter-excutable-resolver';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import net from 'net';

import { DebugAdapterForkExecutable, DebugStreamConnection } from '@opensumi/ide-debug';

import { CustomChildProcess, CustomChildProcessModule } from '../../../ext.process-base';
import { CustomChildProcess, CustomChildProcessModule } from '../../../../common/ext.process';

import { DirectDebugAdapter } from './abstract-debug-adapter-session';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DEFAULT_VSCODE_ENGINE_VERSION } from '@opensumi/ide-core-common/lib/con
import { OverviewRulerLane } from '@opensumi/ide-editor';

import { IExtensionHostService } from '../../../common';
import { ExtHostAppConfig } from '../../../common/ext.process';
import {
ExtHostAPIIdentifier,
IExtHostDebugService,
Expand All @@ -18,7 +19,6 @@ import { ViewColumn } from '../../../common/vscode/enums';
import * as extTypes from '../../../common/vscode/ext-types';
import * as fileSystemTypes from '../../../common/vscode/file-system';
import { IExtHostLocalization } from '../../../common/vscode/localization';
import { ExtHostAppConfig } from '../../ext.process-base';

import { ExtHostDebug, createDebugApiFactory } from './debug';
import { ExtensionDocumentDataManagerImpl } from './doc';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
validateConstraint,
} from '@opensumi/ide-core-common';

import { IBuiltInCommand } from '../../../common/ext.process';
import {
ArgumentProcessor,
CommandHandler,
Expand All @@ -26,7 +27,6 @@ import * as extHostTypeConverter from '../../../common/vscode/converter';
import { Disposable, Location, Position, Range } from '../../../common/vscode/ext-types';
import * as modes from '../../../common/vscode/model.api';
import { CommandDto } from '../../../common/vscode/scm';
import { IBuiltInCommand } from '../../ext.process-base';

import { ExtensionHostEditorService } from './editor/editor.host';
import { ApiCommand, ApiCommandResult, newCommands } from './ext.host.api.command';
Expand Down
7 changes: 4 additions & 3 deletions packages/extension/src/hosted/ext.host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import {
arrays,
timeout,
} from '@opensumi/ide-core-common';
import { AppConfig } from '@opensumi/ide-core-node/lib/types';
import { join } from '@opensumi/ide-utils/lib/path';

import { EXTENSION_EXTEND_SERVICE_PREFIX, IExtendProxy, IExtensionHostService, getExtensionId } from '../common';
import { ActivatedExtension, ActivatedExtensionJSON, ExtensionsActivator } from '../common/activator';
import { ExtHostAppConfig } from '../common/ext.process';
import {
ExtHostAPIIdentifier,
ExtensionIdentifier,
Expand Down Expand Up @@ -107,7 +107,7 @@ class VSCodeAPIImpl extends ApiImplFactory {
extHost: IExtensionHostService,
injector: Injector,
) {
return createVSCodeAPIFactory(rpcProtocol, extHost, injector.get(AppConfig));
return createVSCodeAPIFactory(rpcProtocol, extHost, injector.get(ExtHostAppConfig));
}
}

Expand All @@ -117,7 +117,8 @@ class OpenSumiAPIImpl extends ApiImplFactory {
extHost: IExtensionHostService,
injector: Injector,
) {
return createSumiAPIFactory(rpcProtocol, extHost, 'node', injector.get(IReporter));
const appConfig: ExtHostAppConfig = injector.get(ExtHostAppConfig);
return createSumiAPIFactory(rpcProtocol, extHost, 'node', injector.get(IReporter), appConfig.sumiApiExtenders);
}
}

Expand Down
57 changes: 4 additions & 53 deletions packages/extension/src/hosted/ext.process-base.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import net from 'net';
import { performance } from 'perf_hooks';
import Stream from 'stream';

import { ConstructorOf, Injector } from '@opensumi/di';
import { Injector } from '@opensumi/di';
import { SumiConnectionMultiplexer, createExtMessageIO } from '@opensumi/ide-connection';
import { NetSocketConnection } from '@opensumi/ide-connection/lib/common/connection';
import {
Emitter,
ILogService,
IReporter,
LogLevel,
ReporterProcessMessage,
isPromiseCanceledError,
locale,
setLanguageId,
} from '@opensumi/ide-core-common';
import { argv } from '@opensumi/ide-core-common/lib/node/cli';
import { AppConfig } from '@opensumi/ide-core-node/lib/types';

import { IExtensionHostService, KT_APP_CONFIG_KEY, KT_PROCESS_SOCK_OPTION_KEY, ProcessMessageType } from '../common';
import { CommandHandler } from '../common/vscode';
import { ExtHostAppConfig, ExtProcessConfig } from '../common/ext.process';
import { knownProtocols } from '../common/vscode/protocols';

import { setPerformance } from './api/vscode/language/util';
Expand All @@ -33,51 +29,6 @@ setPerformance(performance);
Error.stackTraceLimit = 100;
let logger: any = console;
let preload: IExtensionHostService;
export interface IBuiltInCommand {
id: string;
handler: CommandHandler;
}

export interface CustomChildProcess {
stdin: Stream.Writable;
stdout: Stream.Readable;
kill: () => void;
}

export interface CustomChildProcessModule {
spawn(command: string, args: string | string[], options: any): CustomChildProcess;
}

export interface ExtHostAppConfig extends Partial<AppConfig> {
builtinCommands?: IBuiltInCommand[];
customDebugChildProcess?: CustomChildProcessModule;
/**
* 集成方自定义 vscode.version 版本
* 设置该参数可能会导致插件运行异常
* @type {string} 插件版本号
* @memberof ExtHostAppConfig
*/
customVSCodeEngineVersion?: string;
}

export interface ExtProcessConfig {
injector?: Injector;
LogServiceClass?: ConstructorOf<ILogService>;
logDir?: string;
logLevel?: LogLevel;
/**
* 这种 command 只有插件能调用到,且只能在插件进程调用到
*/
builtinCommands?: IBuiltInCommand[];
customDebugChildProcess?: CustomChildProcessModule;
customVSCodeEngineVersion?: string;
/**
* control rpcProtocol message timeout
* default -1,it means disable
*/
rpcMessageTimeout?: number;
}

async function initRPCProtocol(extInjector: Injector): Promise<any> {
const extConnection = argv[KT_PROCESS_SOCK_OPTION_KEY];

Expand All @@ -86,7 +37,7 @@ async function initRPCProtocol(extInjector: Injector): Promise<any> {

const socket = net.createConnection(JSON.parse(extConnection));

const appConfig = extInjector.get(AppConfig);
const appConfig: ExtHostAppConfig = extInjector.get(ExtHostAppConfig);

const extProtocol = new SumiConnectionMultiplexer(new NetSocketConnection(socket), {
timeout: appConfig.rpcMessageTimeout,
Expand Down Expand Up @@ -136,7 +87,7 @@ export async function extProcessInit(config: ExtProcessConfig = {}) {
const reporterEmitter = new Emitter<ReporterProcessMessage>();
extInjector.addProviders(
{
token: AppConfig,
token: ExtHostAppConfig,
useValue: { ...extAppConfig, ...extConfig },
},
{
Expand Down
15 changes: 8 additions & 7 deletions packages/extension/src/hosted/extension-log2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ import {
SupportLogNamespace,
getNodeRequire,
} from '@opensumi/ide-core-common';
import { AppConfig } from '@opensumi/ide-core-node/lib/types';
import { LogServiceManager } from '@opensumi/ide-logs/lib/node/log-manager';

import { ExtHostAppConfig } from '../common/ext.process';

export class ExtensionLogger2 implements IExtensionLogger {
private injector: Injector;
private loggerManager: LogServiceManager;
private logger: ILogService;
private config: AppConfig;
private config: ExtHostAppConfig;

constructor(injector: Injector) {
this.injector = injector;
this.config = this.injector.get(AppConfig);
this.config = this.injector.get(ExtHostAppConfig);
this.injectLogService();

this.loggerManager = this.injector.get(LogServiceManager);
// 这块不是非常合理,插件进程引用了 Node 主进程的代码,先改为多例方式防止 AppConfig 找不到的问题
this.loggerManager = this.injector.get(LogServiceManager, [this.config]);
this.logger = this.loggerManager.getLogger(SupportLogNamespace.ExtensionHost, this.config);
}

Expand All @@ -29,7 +30,7 @@ export class ExtensionLogger2 implements IExtensionLogger {
const LogServiceClass = this.config.LogServiceClass;

this.injector.overrideProviders({
token: AppConfig,
token: ExtHostAppConfig,
useValue: Object.assign({}, this.config, { LogServiceClass }),
});
} else if (this.config.extLogServiceClassPath) {
Expand All @@ -39,7 +40,7 @@ export class ExtensionLogger2 implements IExtensionLogger {
LogServiceClass = LogServiceClass.default;
}
this.injector.overrideProviders({
token: AppConfig,
token: ExtHostAppConfig,
useValue: Object.assign({}, this.config, { LogServiceClass }),
});
}
Expand Down
7 changes: 2 additions & 5 deletions packages/logs-core/src/node/log-manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path';

import { Autowired, ConstructorOf, Injectable } from '@opensumi/di';
import { ConstructorOf, Injectable, Optional } from '@opensumi/di';
import { Emitter } from '@opensumi/ide-core-common';
import { AppConfig } from '@opensumi/ide-core-node/lib/types';

Expand All @@ -19,17 +19,14 @@ import { cleanAllLogs, cleanExpiredLogs, cleanOldLogs, getLogFolder, getLogZipAr

@Injectable()
export class LogServiceManager implements ILogServiceManager {
@Autowired(AppConfig)
private appConfig: AppConfig;

protected readonly logLevelChangeEmitter = new Emitter<LogLevel>();
private globalLogLevel: LogLevel;
private logMap = new Map<SupportLogNamespace, ILogService>();
private logRootFolderPath: string;
private logFolderPath: string;
private LogServiceClass: ConstructorOf<ILogService>;

constructor() {
constructor(@Optional(AppConfig) private appConfig: AppConfig) {
Comment thread
hacke2 marked this conversation as resolved.
this.init({
logDir: this.appConfig.logDir,
logLevel: this.appConfig.logLevel,
Expand Down