Retry Policy

A retry policy and the attempts it produced. A policy shown alone reads as reasonable right up until you see it fired four times in ninety milliseconds — the attempt list is what proves the policy running is the one configured.

src/components/ui/retry-policy.tsx

About

From the component's own source, where it was written.

A retry policy and the attempts it produced.

Configuration and history in one component on purpose. A policy shown alone reads as reasonable — three attempts, exponential backoff — right up until you see it fired four times in ninety milliseconds because the backoff was never applied. The attempt list is what proves the policy is the one running.

**Jitter is shown as a range, not a number.** A backoff without jitter is how a thousand clients retry in lockstep and turn one outage into two, and a UI that renders "2s" for a delay that is actually 1.4–2.6s hides whether jitter is configured at all.

The projected schedule is computed from the policy, so a policy that would wait eleven minutes on its last attempt says so before anyone ships it.

Install

npx astralyx-ui add retry-policy

Usage

import { RetryPolicy } from '@/components/ui/retry-policy'

<RetryPolicy maxAttempts={4} baseDelayMs={500} factor={2} jitter={0.3} attempts={attempts} />

Composer

Change the props and the source below follows.

Projected schedule

4 attempts · up to 3.5s of waiting
350ms–650ms700ms–1.3s1.4s–2.6s

Attempts

  • #1failed503 from the embedding service09:41:02
  • #2failedafter 520ms503 from the embedding service09:41:03
  • #3succeededafter 1.2s09:41:04
Props
tsx
<RetryPolicy
  maxAttempts={4}
  baseDelayMs={500}
  factor={2}
  jitter={0.3}
  attempts={attempts}
/>

Examples

Two failures then a success

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

RetryPolicy

Extends Omit<ComponentProps<'div'>, 'children'>.

PropTypeDefaultDescription
maxAttemptsnumberrequiredThe policy. The projected schedule is computed from it, so a policy that would wait eleven minutes on its last attempt says so before anyone ships it.
baseDelayMsnumberrequiredThe policy. The projected schedule is computed from it, so a policy that would wait eleven minutes on its last attempt says so before anyone ships it.
factornumber2The policy. The projected schedule is computed from it, so a policy that would wait eleven minutes on its last attempt says so before anyone ships it.
maxDelayMsnumber—The policy. The projected schedule is computed from it, so a policy that would wait eleven minutes on its last attempt says so before anyone ships it.
jitternumber0Rendered as a range, not a point. A delay shown as “2s” hides whether jitter is configured at all — and without it a thousand clients retry in lockstep and turn one outage into two.
attemptsRetryAttempt[][]{ attempt, at?, outcome, waitedMs?, error? }. The history that proves the configured policy is the one running.
formatDelay(ms: number) => stringdefaultDelay—
scheduleLabelstring'Projected schedule'—
attemptsLabelstring'Attempts'—
noAttemptsLabelstring'Not retried yet.'—
noJitterLabelstring'no jitter — clients will retry in lockstep'—

Types

RetryAttempt

A retry policy and the attempts it produced.

FieldTypeDescription
attemptnumber—
at?stringAlready formatted — this component does not own your locale.
outcome'failed' | 'succeeded' | 'gave-up'—
waitedMs?numberMilliseconds waited before this attempt.
error?ReactNode—