mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-20 18:14:29 -07:00
fix: resolve lifecycle memory leaks by cleaning up listeners and root closures (#25049)
This commit is contained in:
@@ -208,6 +208,7 @@ describe('ShellExecutionService', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
ExecutionLifecycleService.resetForTest();
|
||||
ShellExecutionService.resetForTest();
|
||||
mockSerializeTerminalToObject.mockReturnValue([]);
|
||||
mockIsBinary.mockReturnValue(false);
|
||||
mockPlatform.mockReturnValue('linux');
|
||||
@@ -1247,6 +1248,8 @@ describe('ShellExecutionService child_process fallback', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
ExecutionLifecycleService.resetForTest();
|
||||
ShellExecutionService.resetForTest();
|
||||
|
||||
mockIsBinary.mockReturnValue(false);
|
||||
mockPlatform.mockReturnValue('linux');
|
||||
@@ -1662,6 +1665,8 @@ describe('ShellExecutionService execution method selection', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
ExecutionLifecycleService.resetForTest();
|
||||
ShellExecutionService.resetForTest();
|
||||
onOutputEventMock = vi.fn();
|
||||
|
||||
// Mock for pty
|
||||
@@ -1786,6 +1791,8 @@ describe('ShellExecutionService environment variables', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
ExecutionLifecycleService.resetForTest();
|
||||
ShellExecutionService.resetForTest();
|
||||
vi.resetModules(); // Reset modules to ensure process.env changes are fresh
|
||||
|
||||
// Mock for pty
|
||||
|
||||
@@ -704,7 +704,10 @@ export class ShellExecutionService {
|
||||
|
||||
const finalStrippedOutput = stripAnsi(combinedOutput).trim();
|
||||
const exitCode = code;
|
||||
const exitSignal = signal ? os.constants.signals[signal] : null;
|
||||
const exitSignal =
|
||||
signal && os.constants.signals
|
||||
? (os.constants.signals[signal] ?? null)
|
||||
: null;
|
||||
|
||||
const resultPayload: ShellExecutionResult = {
|
||||
rawOutput: Buffer.from(''),
|
||||
@@ -1503,4 +1506,16 @@ export class ShellExecutionService {
|
||||
signal: info.signal,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the internal state of the ShellExecutionService.
|
||||
* This is intended for use in tests to ensure isolation.
|
||||
*/
|
||||
static resetForTest(): void {
|
||||
this.activePtys.clear();
|
||||
this.activeChildProcesses.clear();
|
||||
this.backgroundLogPids.clear();
|
||||
this.backgroundLogStreams.clear();
|
||||
this.backgroundProcessHistory.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,7 +812,7 @@ type StatusChangeListener = (
|
||||
serverName: string,
|
||||
status: MCPServerStatus,
|
||||
) => void;
|
||||
const statusChangeListeners: StatusChangeListener[] = [];
|
||||
const statusChangeListeners: Set<StatusChangeListener> = new Set();
|
||||
|
||||
/**
|
||||
* Add a listener for MCP server status changes
|
||||
@@ -820,7 +820,7 @@ const statusChangeListeners: StatusChangeListener[] = [];
|
||||
export function addMCPStatusChangeListener(
|
||||
listener: StatusChangeListener,
|
||||
): void {
|
||||
statusChangeListeners.push(listener);
|
||||
statusChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -829,10 +829,7 @@ export function addMCPStatusChangeListener(
|
||||
export function removeMCPStatusChangeListener(
|
||||
listener: StatusChangeListener,
|
||||
): void {
|
||||
const index = statusChangeListeners.indexOf(listener);
|
||||
if (index !== -1) {
|
||||
statusChangeListeners.splice(index, 1);
|
||||
}
|
||||
statusChangeListeners.delete(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user