mirror of
https://github.com/logos-messaging/logos-messaging-js.git
synced 2026-01-24 19:03:12 +00:00
* feat(sds): messages with lost deps are delivered This is to re-enable participation in the SDS protocol. Meaning the received message with missing dependencies becomes part of the causal history, re-enabling acknowledgements. * fix(sds): avoid overflow in message history storage * feat(reliable-channel): Emit a "Synced" Status with message counts Return a "synced" or "syncing" status on `ReliableChannel.status` that let the developer know whether messages are missing, and if so, how many. * fix: clean up subscriptions, intervals and timeouts when stopping # Conflicts: # packages/sdk/src/reliable_channel/reliable_channel.ts * chore: extract random timeout * fix rebase * revert listener changes * typo * Ensuring no inconsistency on missing message * test: streamline, stop channels * clear sync status sets when stopping channel * prevent sync status event spam * test: improve naming * try/catch for callback * encapsulate/simplify reliable channel API * sanity checks * test: ensure sync status cleanup
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
import { Logger } from "@waku/utils";
|
|
|
|
const log = new Logger("sdk:random-timeout");
|
|
|
|
/**
|
|
* Enables waiting a random time before doing an action (using `setTimeout`),
|
|
* with possibility to apply a multiplier to manipulate said time.
|
|
*/
|
|
export class RandomTimeout {
|
|
private timeout: ReturnType<typeof setTimeout> | undefined;
|
|
|
|
public constructor(
|
|
/**
|
|
* The maximum interval one would wait before the call is made, in milliseconds.
|
|
*/
|
|
private maxIntervalMs: number,
|
|
/**
|
|
* When not zero: Anytime a call is made, then a new call will be rescheduled
|
|
* using this multiplier
|
|
*/
|
|
private multiplierOnCall: number,
|
|
/**
|
|
* The function to call when the timer is reached
|
|
*/
|
|
private callback: () => void | Promise<void>
|
|
) {
|
|
if (!Number.isFinite(maxIntervalMs) || maxIntervalMs < 0) {
|
|
throw new Error(
|
|
`maxIntervalMs must be a non-negative finite number, got: ${maxIntervalMs}`
|
|
);
|
|
}
|
|
if (!Number.isFinite(multiplierOnCall)) {
|
|
throw new Error(
|
|
`multiplierOnCall must be a finite number, got: ${multiplierOnCall}`
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Use to start the timer. If a timer was already set, it deletes it and
|
|
* schedule a new one.
|
|
* @param multiplier applied to [[maxIntervalMs]]
|
|
*/
|
|
public restart(multiplier: number = 1): void {
|
|
this.stop();
|
|
|
|
if (this.maxIntervalMs) {
|
|
const timeoutMs = Math.random() * this.maxIntervalMs * multiplier;
|
|
|
|
this.timeout = setTimeout(() => {
|
|
try {
|
|
void this.callback();
|
|
} catch (error) {
|
|
log.error("Error in RandomTimeout callback:", error);
|
|
}
|
|
void this.restart(this.multiplierOnCall);
|
|
}, timeoutMs);
|
|
}
|
|
}
|
|
|
|
public stop(): void {
|
|
if (this.timeout) {
|
|
clearTimeout(this.timeout);
|
|
this.timeout = undefined;
|
|
}
|
|
}
|
|
}
|