import { LDLogger } from '../../api/logging/LDLogger'; import { FailureKind } from '../../errors'; import { ResetPolicy } from './ResetPolicy'; /** * Configuration for a {@link RetryState}. * * Values are trusted, not validated: each delay bound must be a positive, * finite number of milliseconds, and the operating cadence a non-negative, * finite one. The factories ({@link forStreaming}, {@link forPolling}) are the * validated entry points for anything user-configurable; a caller constructing * directly is expected to supply known-good values. */ export interface RetryStateConfig { /** The delay before the first retry in the normal regime, in milliseconds. */ normalInitialDelayMs: number; /** The longest normal-regime delay, in milliseconds. */ normalCeilingMs: number; /** The delay before the first retry in the extended regime, in milliseconds. */ extendedInitialDelayMs: number; /** * The longest extended-regime delay, in milliseconds; never less than the * extended initial delay. */ extendedCeilingMs: number; /** Decides when the retry state resets. */ resetPolicy: ResetPolicy; /** * The wait between healthy operations, in milliseconds. No wait is ever * shorter than this. Zero (the default) for a component that operates * continuously. */ operatingCadenceMs?: number; /** The random source used for jitter. */ random?: () => number; } /** * Tracks how long a data source, or another long-running component, should * wait before its next attempt. * * Recording a failure advances the state and decides the next wait, which * {@link RetryState.nextDelay} reports: the delay doubles with each * consecutive failure, from the current regime's initial delay up to its * ceiling, less a random jitter of up to half of it, and never less than the * operating cadence. An unexpected failure moves the state to the extended * regime, which raises both bounds; a normal failure that follows cannot lower * them. The bounds stay raised until the reset policy is satisfied. A * server-directed retry time, once applied, replaces the regime's initial * delay as the base of the computation; the ceiling continues to apply. * * Recording a success sets the next wait back to the operating cadence, even * while the retry state is raised, because a backoff wait applies to a retry * and not to every operation. * * A retry state never starts timers, performs I/O, or logs; callers schedule * the waits it computes. Use one instance per component; instances are never * shared between components. */ export interface RetryState { /** * The wait, in milliseconds, before the next operation, as the last * recorded outcome decided it. Reading it has no side effects. */ readonly nextDelay: number; /** * Records a failed attempt and decides the wait before the next one. * * The state advances before the wait is computed, so {@link RetryState.nextDelay} * always reflects the failure just recorded. Callers should read it in the * same turn, before any other outcome is recorded. */ recordFailure(kind: FailureKind): void; /** * Records a successful operation and resets the retry state if that is now * enough to satisfy the reset policy. */ recordSuccess(): void; /** * Applies a server-directed retry time. * * The value replaces the base of the delay computation and restarts the * doubling sequence, taking precedence over the current regime's initial * delay — including the extended regime's. The computed delay is still * bounded by the regime's ceiling. The value stays in effect until another * one arrives, including across a reset. Non-finite or negative values are * ignored; callers are expected to have validated and capped the value at * its point of entry. */ applyServerDirectedRetry(delayMs: number): void; } /** * Builds a retry state from explicit bounds. See {@link RetryStateConfig} for * the contract on the values. */ export declare function createRetryState(config: RetryStateConfig): RetryState; /** * Builds the retry state for a streaming data source: no wait during healthy * operation, a normal regime running from the configured initial delay up to * a 30 second ceiling, an extended regime of 5 minutes up to 1 hour, and a * reset once a connection has been healthy for 60 seconds. * * The initial delay is validated here; the documented default of 1 second * stands in for anything that is not a positive, finite number. A configured * delay above the normal ceiling is clamped to it, while the extended regime * never starts below the configured delay. */ export declare function forStreaming(initialReconnectDelayMs: number, logger?: LDLogger): RetryState; /** * Builds the retry state for a polling data source: the poll interval is the * operating cadence, so no wait is ever shorter than it; in the normal regime * both bounds are the interval itself, so a normal failure simply polls again * on schedule; the extended regime runs from 5 minutes (or the interval, if * longer) up to 1 hour (or the interval, if longer); and the state resets * after two successful polls in a row. * * The poll interval is validated here; the documented default of 30 seconds * stands in for anything that is not a positive, finite number. */ export declare function forPolling(pollIntervalMs: number, logger?: LDLogger): RetryState; //# sourceMappingURL=RetryState.d.ts.map