@cronstamp/clientlib
Version:
Client library for cronstamp, a blockchain-based document timestamping and verification service.
80 lines • 2.69 kB
JavaScript
export async function sleep_s(seconds) {
await sleep_ms(seconds * 1000);
}
export async function sleep_ms(milliseconds) {
await new Promise((resolve) => setTimeout(resolve, milliseconds));
}
/**
* Get time until next attempt using exponential backoff
* Defaults to 1.35^attempt seconds. This results in about four minutes total time for 15 attempts.
* The first attempt always runs immediately
*/
export class ExponentialBackoff {
startTime;
lastSleepTime;
attempt;
maxAttempts;
interval;
rate;
/**
* Exponential backoff starting at a specified time
* Defaults to 1.35^attempt seconds. This results in about four minutes total time for 15 attempts.
*
* @param maxAttempts attempt at which to stop (exclusive, starting at 0)
* @param interval
* @param rate
* @param startTime unix timestamp in ms
*/
constructor(maxAttempts = 15, rate = 1.35, interval = 1000, startTime = Date.now()) {
this.startTime = startTime;
this.lastSleepTime = startTime;
this.interval = interval;
this.rate = rate;
this.attempt = 0;
this.maxAttempts = maxAttempts;
}
/**
* Get the delay until next attempt, assuming the last attempt was the previous index. Time elapsed since the last call is subtracted from the delay.
* Attempt 0 is always immediate.
*/
getDelayForNextAttempt() {
if (this.attempt == 0) {
return 0;
}
const delay_ms = this.interval * Math.pow(this.rate, this.attempt);
return Math.max(this.lastSleepTime - Date.now() + delay_ms, 0);
}
/**
* Wait for the next attempt. Time elapsed since the last call is subtracted from the delay.
* Attempt 0 is always immediate.
* Increases internal attempt counter
*
* @returns true, if waited for the time of the current step, false if the maxAttempt was reached
*/
async waitForNextAttempt() {
if (!this.isActive()) {
return false;
}
await sleep_ms(this.getDelayForNextAttempt());
this.lastSleepTime = Date.now();
this.attempt++;
return true;
}
/**
* Gets the total time in milliseconds this exponential backoff will take, if all attempts are used.
*/
getTotalTime() {
let total = 0;
for (let attempt = 0; attempt < this.maxAttempts; attempt++) {
total += this.interval * Math.pow(this.rate, attempt);
}
return total;
}
/**
* Returns true, if there are attempts left
*/
isActive() {
return this.attempt < this.maxAttempts;
}
}
//# sourceMappingURL=time.js.map