Skip to content

Commit

Permalink
feat: add new poll util
Browse files Browse the repository at this point in the history
  • Loading branch information
juliannemarik committed Oct 6, 2023
1 parent 23a9fc3 commit 22ec2e7
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/common/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from "./dasherize";
export * from "./titleize";
export * from "./memoize";
export * from "./getEnvironmentFromPortalUrl";
export * from "./poll";
41 changes: 41 additions & 0 deletions packages/common/src/utils/poll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Function to poll a provided request until a validation
* state or timeout is reached
* @param requestFn
* @param validationFn
* @param opts
*/
export const poll = async (
requestFn: () => any,
validationFn: (resp: any) => boolean,
opts?: {
timeout?: number;
timeBetweenRequests?: number;
}
): Promise<any> => {
const { timeout = 30000, timeBetweenRequests = 3000 } = opts || {};
let resp: any;
let requestCount = 0;

do {
// on subsequent requests, check if the configured
// timeout has been reached
// If YES: throw an error
// If NO: delay before the next request
if (requestCount > 0) {
if (requestCount * timeBetweenRequests >= timeout) {
throw new Error("Polling timeout");
}
await delay(timeBetweenRequests);
}

resp = await requestFn();
requestCount++;
} while (!validationFn(resp));

return resp;
};

const delay = (milliseconds: number) => {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
};
37 changes: 37 additions & 0 deletions packages/common/test/utils/poll.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { poll } from "../../src/utils/poll";

describe("poll", () => {
it("polls the request function until the validation function succeeds", async () => {
const validationFn = (resp) => resp && resp.id;
const requestFnSpy = jasmine
.createSpy()
.and.returnValues(Promise.resolve({}), Promise.resolve({ id: "00c" }));

const chk = await poll(
requestFnSpy,
validationFn,
// set delay to 0 for testing purposes
{ timeBetweenRequests: 0 }
);
expect(requestFnSpy).toHaveBeenCalledTimes(2);
expect(chk.id).toBe("00c");
});
it("throws an error when the timeout is reached", async () => {
const validationFn = (resp) => resp && resp.id;
const requestFnSpy = jasmine
.createSpy()
.and.returnValue(Promise.resolve({}));

let errorMessage = "Polling timeout";
try {
await poll(requestFnSpy, validationFn, {
timeBetweenRequests: 100,
timeout: 200,
});
} catch (error) {
errorMessage = error.message;
}
expect(requestFnSpy).toHaveBeenCalledTimes(2);
expect(errorMessage).toBe("Polling timeout");
});
});

0 comments on commit 22ec2e7

Please sign in to comment.