Skip to content

Commit

Permalink
Add a withTimeout function to set a timeout for a request
Browse files Browse the repository at this point in the history
  • Loading branch information
jerelmiller committed Mar 13, 2024
1 parent 8313124 commit 96858c3
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/extension/__tests__/rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,9 @@ test("times out if no message received within configured timeout", async () => {
const adapter = createTestAdapter();
const client = createRpcClient<Message>(adapter);

const promise = client.request("add", { x: 1, y: 2 }, { timeoutMs: 1000 });
const promise = client.withTimeout(1000).request("add", { x: 1, y: 2 });

jest.advanceTimersByTime(1_000);
jest.advanceTimersByTime(1000);

await expect(promise).rejects.toEqual(
new Error("Timeout waiting for message")
Expand Down
21 changes: 16 additions & 5 deletions src/extension/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
type MessageCollection = Record<string, (...parameters: [SafeAny]) => SafeAny>;

export interface RpcClient<Messages extends MessageCollection> {
withTimeout: (timeoutMs: number) => RpcClient<Messages>;
request: <TName extends keyof Messages & string>(
name: TName,
params: Parameters<Messages[TName]>[0],
options?: { timeoutMs?: number }
params: Parameters<Messages[TName]>[0]
) => Promise<Awaited<ReturnType<Messages[TName]>>>;
}

Expand All @@ -27,15 +27,24 @@ const DEFAULT_TIMEOUT = 30_000;
export function createRpcClient<Messages extends MessageCollection>(
adapter: MessageAdapter<RPCRequestMessage>
): RpcClient<Messages> {
return {
request: (name, params, options) => {
let timeout = DEFAULT_TIMEOUT;

const client: RpcClient<Messages> = {
withTimeout: (timeoutMs) => {
timeout = timeoutMs;
return client;
},
request: (name, params) => {
const configuredTimeout = timeout;
timeout = DEFAULT_TIMEOUT;

return new Promise<SafeAny>((resolve, reject) => {
const id = createId();

const timeout = setTimeout(() => {
removeListener();
reject(new Error("Timeout waiting for message"));
}, options?.timeoutMs ?? DEFAULT_TIMEOUT);
}, configuredTimeout);

const removeListener = adapter.addListener((message) => {
if (!isRPCResponseMessage(message) || message.sourceId !== id) {
Expand All @@ -62,6 +71,8 @@ export function createRpcClient<Messages extends MessageCollection>(
});
},
};

return client;
}

export function createRpcHandler<Messages extends MessageCollection>(
Expand Down

0 comments on commit 96858c3

Please sign in to comment.