UNPKG

serverless-spy

Version:

CDK-based library for writing elegant integration tests on AWS serverless architecture and an additional web console to monitor events in real time.

60 lines (59 loc) 2.58 kB
import { sleep } from "./utils/sleep"; import { WaiterState } from "./waiter"; const exponentialBackoffWithJitter = (minDelay, maxDelay, attemptCeiling, attempt) => { if (attempt > attemptCeiling) return maxDelay; const delay = minDelay * 2 ** (attempt - 1); return randomInRange(minDelay, delay); }; const randomInRange = (min, max) => min + Math.random() * (max - min); export const runPolling = async ({ minDelay, maxDelay, maxWaitTime, abortController, client, abortSignal }, input, acceptorChecks) => { const observedResponses = {}; const { state, reason } = await acceptorChecks(client, input); if (reason) { const message = createMessageFromResponse(reason); observedResponses[message] |= 0; observedResponses[message] += 1; } if (state !== WaiterState.RETRY) { return { state, reason, observedResponses }; } let currentAttempt = 1; const waitUntil = Date.now() + maxWaitTime * 1000; const attemptCeiling = Math.log(maxDelay / minDelay) / Math.log(2) + 1; while (true) { if (abortController?.signal?.aborted || abortSignal?.aborted) { const message = "AbortController signal aborted."; observedResponses[message] |= 0; observedResponses[message] += 1; return { state: WaiterState.ABORTED, observedResponses }; } const delay = exponentialBackoffWithJitter(minDelay, maxDelay, attemptCeiling, currentAttempt); if (Date.now() + delay * 1000 > waitUntil) { return { state: WaiterState.TIMEOUT, observedResponses }; } await sleep(delay); const { state, reason } = await acceptorChecks(client, input); if (reason) { const message = createMessageFromResponse(reason); observedResponses[message] |= 0; observedResponses[message] += 1; } if (state !== WaiterState.RETRY) { return { state, reason, observedResponses }; } currentAttempt += 1; } }; const createMessageFromResponse = (reason) => { if (reason?.$responseBodyText) { return `Deserialization error for body: ${reason.$responseBodyText}`; } if (reason?.$metadata?.httpStatusCode) { if (reason.$response || reason.message) { return `${reason.$response.statusCode ?? reason.$metadata.httpStatusCode ?? "Unknown"}: ${reason.message}`; } return `${reason.$metadata.httpStatusCode}: OK`; } return String(reason?.message ?? JSON.stringify(reason) ?? "Unknown"); };