@segment/analytics-react-native
Version:
The hassle-free way to add Segment analytics to your React-Native app.
125 lines • 5.27 kB
TypeScript
import type { Persistor } from '@segment/sovran-react-native';
import type { LoggerType, RateLimitConfig, BackoffConfig } from '../types';
export declare enum RetryState {
READY = "READY",
RATE_LIMITED = "RATE_LIMITED",
BACKING_OFF = "BACKING_OFF"
}
export declare enum RetryResult {
RATE_LIMITED = "rate_limited",
BACKED_OFF = "backed_off",
LIMIT_EXCEEDED = "limit_exceeded"
}
/**
* Manages retry state for rate limiting (429) and transient errors (5xx).
*
* State machine: READY → RATE_LIMITED (429) or BACKING_OFF (5xx) → READY
* - READY: uploads proceed normally
* - RATE_LIMITED: server returned 429; uploads blocked until Retry-After expires
* - BACKING_OFF: transient error; exponential backoff until wait expires
*
* Designed for concurrent batch uploads (Promise.all). Multiple batches can
* fail simultaneously with different errors or partially succeed. When
* consolidating concurrent wait times, takes the shorter wait (eager retry).
*
* Uses a global retry counter since batches are re-chunked from the event
* queue on each flush and have no stable identities.
*/
export declare class RetryManager {
private store;
private rateLimitConfig?;
private backoffConfig?;
private logger?;
constructor(storeId: string, persistor: Persistor | undefined, rateLimitConfig?: RateLimitConfig, backoffConfig?: BackoffConfig, logger?: LoggerType);
/**
* Create sovran store with persistence fallback.
* Tries persisted store first, falls back to in-memory on failure.
*/
private createStore;
/** Extract error message from unknown error type. */
private getErrorMessage;
/**
* Check if uploads can proceed. Transitions to READY if wait time has passed.
* Validates persisted state to handle clock changes or corruption.
*/
canRetry(): Promise<boolean>;
/**
* Clamp retry-after seconds to valid range [0, maxRetryInterval].
*/
private clampRetryAfter;
/**
* Handle a response that carries a server-directed wait via the Retry-After
* header. Originally added for 429 rate limiting, this is the authoritative
* "the server told us exactly how long to wait" path and is reused for any
* retryable status code (429, 529, 503, 408, …) that includes Retry-After.
*
* Uses the server-specified wait time (clamped to maxRetryInterval), pauses
* all uploads, and enforces the same maxRetryCount / maxRateLimitDuration
* safety valves as the 429 path.
*/
handleRetryAfter(retryAfterSeconds: number): Promise<RetryResult | undefined>;
/**
* Handle a 429 rate limit response.
* Delegates to the shared Retry-After (server-directed wait) path.
*/
handle429(retryAfterSeconds: number): Promise<RetryResult | undefined>;
/**
* Handle a transient error (5xx, network failure).
* Uses exponential backoff to calculate wait time.
*/
handleTransientError(): Promise<RetryResult | undefined>;
/** Reset the state machine to READY with retry count 0. */
reset(): Promise<void>;
/** Get the current retry count (used for X-Retry-Count header). */
getRetryCount(): Promise<number>;
/**
* Compute new retry state based on current state and error type.
* Returns the new state and whether retry limits were exceeded.
*/
private computeNewState;
/**
* Map retry state to result enum.
*/
private stateToResult;
/**
* Unified error handler for both 429 and transient errors.
* Dispatches atomically to handle concurrent batch failures.
*
* @param newState - The target state (RATE_LIMITED or BACKING_OFF)
* @param computeWaitUntilTime - Function to compute wait time from current state.
* For 429: returns server-specified Retry-After time (ignores state).
* For transient: computes exponential backoff from state.retryCount.
* @param maxRetryCount - Maximum allowed retry count before reset
* @param maxRetryDuration - Maximum allowed total retry duration (seconds)
* @param now - Current timestamp
*/
private handleError;
/**
* Resolve state precedence when multiple errors occur concurrently.
* Rule: 429 rate limiting takes precedence over transient backoff.
*/
private resolveStatePrecedence;
/**
* Consolidate wait times when multiple errors occur.
* Uses eager strategy (shorter wait) except when transitioning states.
*/
private consolidateWaitTime;
/** Get display name for logging based on retry state. */
private getStateDisplayName;
private calculateBackoff;
private transitionToReady;
/** Check if state enum is valid. */
private isValidStateEnum;
/** Check if firstFailureTime is in the past or null. */
private isValidFirstFailureTime;
/** Check if waitUntilTime is within reasonable bounds. */
private isValidWaitUntilTime;
/** Check if retryCount is non-negative. */
private isValidRetryCount;
/**
* Validate persisted state loaded from storage on app restart.
* Detects clock changes, corruption, or impossibly stale data.
*/
private isPersistedStateValid;
}
//# sourceMappingURL=RetryManager.d.ts.map