Path: blob/main/src/vs/platform/agentHost/node/agentHostService.ts
13394 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Event } from '../../../base/common/event.js';6import { Disposable, toDisposable } from '../../../base/common/lifecycle.js';7import { ILogService, ILoggerService } from '../../log/common/log.js';8import { RemoteLoggerChannelClient } from '../../log/common/logIpc.js';9import { IAgentHostStarter } from '../common/agent.js';10import { AgentHostIpcChannels } from '../common/agentService.js';1112enum Constants {13MaxRestarts = 5,14}1516/**17* Main-process service that manages the agent host utility process lifecycle18* (lazy start, crash recovery, logger forwarding). The renderer communicates19* with the utility process directly via MessagePort - this class does not20* relay any agent service calls.21*/22export class AgentHostProcessManager extends Disposable {2324private _started = false;25private _wasQuitRequested = false;26private _restartCount = 0;2728constructor(29private readonly _starter: IAgentHostStarter,30@ILogService private readonly _logService: ILogService,31@ILoggerService private readonly _loggerService: ILoggerService,32) {33super();3435this._register(this._starter);3637// Start lazily when the first window asks for a connection38if (this._starter.onRequestConnection) {39this._register(Event.once(this._starter.onRequestConnection)(() => this._ensureStarted()));40}4142if (this._starter.onWillShutdown) {43this._register(this._starter.onWillShutdown(() => this._wasQuitRequested = true));44}45}4647private _ensureStarted(): void {48if (!this._started) {49this._start();50}51}5253private async _start(): Promise<void> {54this._started = true;55try {56const connection = await this._starter.start();5758if (this._store.isDisposed) {59connection.store.dispose();60return;61}6263this._logService.info('AgentHostProcessManager: agent host started');6465// Connect logger channel so agent host logs appear in the output channel66this._register(new RemoteLoggerChannelClient(this._loggerService, connection.client.getChannel(AgentHostIpcChannels.Logger)));6768// Handle unexpected exit69this._register(connection.onDidProcessExit(e => {70if (!this._wasQuitRequested && !this._store.isDisposed) {71if (this._restartCount <= Constants.MaxRestarts) {72this._logService.error(`AgentHostProcessManager: agent host terminated unexpectedly with code ${e.code}`);73this._restartCount++;74this._started = false;75connection.store.dispose();76this._start();77} else {78this._logService.error(`AgentHostProcessManager: agent host terminated with code ${e.code}, giving up after ${Constants.MaxRestarts} restarts`);79}80}81}));8283this._register(toDisposable(() => connection.store.dispose()));84} catch (error) {85this._started = false;86this._logService.error('AgentHostProcessManager: failed to start agent host', error);87}88}89}909192