fix(opencode): clear server close timeout (#1224)

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
This commit is contained in:
Isaac Sanchez-Hawkins
2026-05-12 11:00:45 +03:00
committed by GitHub
co-authored by Isaac Sanchez
parent 4cbee27383
commit eeabc304bd
2 changed files with 79 additions and 14 deletions
@@ -90,20 +90,27 @@ export const createGracefulShutdownRuntime = (dependencies) => {
const server = getServer();
if (server) {
await Promise.race([
new Promise((resolve) => {
server.close(() => {
console.log('HTTP server closed');
resolve();
});
}),
new Promise((resolve) => {
setTimeout(() => {
console.warn('Server close timeout reached, forcing shutdown');
resolve();
}, shutdownTimeoutMs);
}),
]);
let closeTimeout = null;
try {
await Promise.race([
new Promise((resolve) => {
server.close(() => {
console.log('HTTP server closed');
resolve();
});
}),
new Promise((resolve) => {
closeTimeout = setTimeout(() => {
console.warn('Server close timeout reached, forcing shutdown');
resolve();
}, shutdownTimeoutMs);
}),
]);
} finally {
if (closeTimeout) {
clearTimeout(closeTimeout);
}
}
}
const uiAuthController = getUiAuthController();
@@ -0,0 +1,58 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import { createGracefulShutdownRuntime } from './shutdown-runtime.js';
const createRuntime = (server) => createGracefulShutdownRuntime({
process: { exit: vi.fn() },
shutdownTimeoutMs: 1000,
getExitOnShutdown: () => false,
getIsShuttingDown: () => false,
setIsShuttingDown: vi.fn(),
syncToHmrState: vi.fn(),
openCodeWatcherRuntime: { stop: vi.fn() },
sessionRuntime: { dispose: vi.fn() },
scheduledTasksRuntime: { stop: vi.fn() },
getHealthCheckInterval: () => null,
clearHealthCheckInterval: vi.fn(),
getTerminalRuntime: () => null,
setTerminalRuntime: vi.fn(),
getMessageStreamRuntime: () => null,
setMessageStreamRuntime: vi.fn(),
shouldSkipOpenCodeStop: () => true,
getOpenCodePort: () => null,
getOpenCodeProcess: () => null,
setOpenCodeProcess: vi.fn(),
killProcessOnPort: vi.fn(),
waitForPortRelease: vi.fn(async () => true),
getServer: () => server,
getUiAuthController: () => null,
setUiAuthController: vi.fn(),
getActiveTunnelController: () => null,
setActiveTunnelController: vi.fn(),
tunnelAuthController: { clearActiveTunnel: vi.fn() },
});
describe('graceful shutdown runtime', () => {
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});
it('clears the server close timeout when the server closes first', async () => {
vi.useFakeTimers();
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const server = {
close: vi.fn((callback) => {
callback();
}),
};
const runtime = createRuntime(server);
await runtime.gracefulShutdown({ exitProcess: false });
await vi.advanceTimersByTimeAsync(1000);
expect(warnSpy).not.toHaveBeenCalledWith('Server close timeout reached, forcing shutdown');
expect(vi.getTimerCount()).toBe(0);
});
});