Synctera.Retry (Synctera v1.0.0)

Copy Markdown View Source

Retry policy for 429 and 5xx responses — the only statuses Synctera's docs confirm are never served from their idempotency cache, and so are always safe to retry without risking a duplicate side effect.

Summary

Functions

Computes the delay in milliseconds before the next retry attempt (0-indexed), using exponential backoff with jitter, unless an explicit retry_after_ms (from a Retry-After header) is given, in which case that takes priority.

Parses a Retry-After header value, which may be either a number of seconds or an HTTP-date, into milliseconds. Returns nil if the header is absent or unparsable.

True for status codes Synctera's idempotency layer never caches, so they're always safe to retry.

Types

t()

@type t() :: %Synctera.Retry{
  base_delay_ms: non_neg_integer(),
  max_delay_ms: non_neg_integer(),
  max_retries: non_neg_integer()
}

Functions

backoff_delay_ms(attempt, config, retry_after_ms)

@spec backoff_delay_ms(non_neg_integer(), t(), non_neg_integer() | nil) ::
  non_neg_integer()

Computes the delay in milliseconds before the next retry attempt (0-indexed), using exponential backoff with jitter, unless an explicit retry_after_ms (from a Retry-After header) is given, in which case that takes priority.

parse_retry_after(header)

@spec parse_retry_after(String.t() | nil) :: non_neg_integer() | nil

Parses a Retry-After header value, which may be either a number of seconds or an HTTP-date, into milliseconds. Returns nil if the header is absent or unparsable.

retryable_status?(status)

@spec retryable_status?(pos_integer()) :: boolean()

True for status codes Synctera's idempotency layer never caches, so they're always safe to retry.