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
4 changes: 2 additions & 2 deletions src/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { KubeConfig } from './config.js';
export class Watch {
public static SERVER_SIDE_CLOSE: object = { error: 'Connection closed on server' };
public config: KubeConfig;
private requestTimeoutMs: number = 30000;

public constructor(config: KubeConfig) {
this.config = config;
Expand Down Expand Up @@ -39,9 +40,8 @@ export class Watch {
const requestInit = await this.config.applyToFetchOptions({});

const controller = new AbortController();
const timeoutSignal = AbortSignal.timeout(30000);
const timeoutSignal = AbortSignal.timeout(this.requestTimeoutMs);
requestInit.signal = AbortSignal.any([controller.signal, timeoutSignal]);
requestInit.signal = controller.signal as AbortSignal;
requestInit.method = 'GET';

let doneCalled: boolean = false;
Expand Down
36 changes: 36 additions & 0 deletions src/watch_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,42 @@ describe('Watch', () => {
s.done();
});

it('should timeout when server takes too long to respond', async (t) => {
const kc = await setupMockSystem(t, (_req: any, _res: any) => {
// Don't respond - simulate a hanging server
});
const watch = new Watch(kc);

// NOTE: Hack around the type system to make the timeout shorter
(watch as any).requestTimeoutMs = 100;

let doneCalled = false;
let doneErr: any;

let doneResolve: () => void;
const donePromise = new Promise<void>((resolve) => {
doneResolve = resolve;
});

await watch.watch(
'/some/path/to/object',
{},
() => {
throw new Error('Unexpected data received - timeout should have occurred before any data');
},
(err: any) => {
doneCalled = true;
doneErr = err;
doneResolve();
},
);

await donePromise;

strictEqual(doneCalled, true);
strictEqual(doneErr.name, 'AbortError');
});

it('should throw on empty config', async () => {
const kc = new KubeConfig();
const watch = new Watch(kc);
Expand Down