Something went wrong. Try again.
TypeScript client for accessing TLE Community.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105import Lacuna from '../lacuna';
// End-to-end cover for the recovery path, with the transport stubbed rather// than the handler: a real Server#call publishes to a real Responses bus,// which runs the real built-in handler, whose retry() re-enters Server#call.// The unit tests either side of this one stub the pieces in the middle.//// The network is stubbed because the live server's rpc_limit is 10,000// requests/minute - genuinely tripping it would mean hammering a shared// server with five figures of traffic.
const slowDown = { code: 1010, message: 'Slow down', data: {} };
/** Makes the transport answer with `failures` RPC limit errors, then succeed. */function stubTransport(lacuna: Lacuna, failures: number) { let calls = 0; const post = jest.fn(async () => { calls += 1; if (calls <= failures) return { error: { id: 1, jsonrpc: '2.0', error: slowDown } }; return { data: { id: 1, jsonrpc: '2.0', result: { attempt: calls } } }; });
lacuna.server.client = { POST: post } as unknown as typeof lacuna.server.client; return post;}
let lacuna: Lacuna;
beforeEach(() => { console.warn = jest.fn(); lacuna = new Lacuna(); lacuna.session.set('test-session');});
test('an RPC limit error is retried until it succeeds, transparently to the caller', async () => { const post = stubTransport(lacuna, 2); lacuna.enableRpcLimitHandler({ baseDelayMs: 1 });
const { result, error } = await lacuna.empire.getStatus();
expect(post).toHaveBeenCalledTimes(3); expect(error).toBeUndefined(); expect(result).toEqual({ attempt: 3 });});
test('gives up after maxRetries and hands the error back to the caller', async () => { const post = stubTransport(lacuna, Infinity); lacuna.enableRpcLimitHandler({ maxRetries: 2, baseDelayMs: 1 });
const { result, error } = await lacuna.empire.getStatus();
// Original call plus two retries. expect(post).toHaveBeenCalledTimes(3); expect(result).toBeUndefined(); expect(error).toEqual(slowDown);});
test('without the handler enabled the RPC limit error is returned as-is', async () => { const post = stubTransport(lacuna, 2);
const { error } = await lacuna.empire.getStatus();
expect(post).toHaveBeenCalledTimes(1); expect(error).toEqual(slowDown);});
test('disabling the handler stops it retrying', async () => { const post = stubTransport(lacuna, 2); const disable = lacuna.enableRpcLimitHandler({ baseDelayMs: 1 }); disable();
const { error } = await lacuna.empire.getStatus();
expect(post).toHaveBeenCalledTimes(1); expect(error).toEqual(slowDown);});
test('an observing subscriber still sees every attempt, even the recovered ones', async () => { stubTransport(lacuna, 2); lacuna.enableRpcLimitHandler({ baseDelayMs: 1 });
const attempts: number[] = []; lacuna.onResponse((event) => { attempts.push(event.attempt); });
await lacuna.empire.getStatus();
// Retries nest: attempt 0's handler is still awaiting attempt 1's, which is // awaiting attempt 2's, so the innermost attempt settles - and reaches this // subscriber - first. All three arrive, which is the point. expect(attempts).toEqual([2, 1, 0]);});
test('the retry depth backstop bounds a handler that always retries', async () => { const post = stubTransport(lacuna, Infinity); lacuna.onResponse((event) => (event.response.error ? event.retry() : undefined));
const { error } = await lacuna.empire.getStatus();
// MAX_RETRY_DEPTH is 10, so the original call plus 10 retries, then stop. expect(post).toHaveBeenCalledTimes(11); expect(error).toEqual(slowDown);});