Перейти к содержанию

Retry Policy — Полный код

Уровень: L3 (deep-dive) | ← Назад к Sync Engine

Файл: frontend/src/offline/sync/retryPolicy.ts

Ст��атегия повторных попыток с exponential backoff и jitter.

const BASE_DELAY_MS = 1000;    // Начальная задержка: 1 секунда
const MAX_DELAY_MS = 60_000;   // Максимальная задержка: 60 секунд
const MAX_RETRIES = 5;         // Максимум повторных попыток

/**
 * Вычислить задержку перед следующей попыткой.
 * Exponential backoff: 1s → 2s → 4s → 8s → 16s → 32s (cap 60s)
 * С jitter ±20% для пре��отвращения thundering herd.
 */
export function getRetryDelay(retryCount: number): number {
  const delay = Math.min(BASE_DELAY_MS * Math.pow(2, retryCount), MAX_DELAY_MS);
  // Jitter: случайное отклонение ±20%
  const jitter = delay * 0.2 * (Math.random() * 2 - 1);
  return Math.round(delay + jitter);
}

/**
 * Определить, нужно ли повторять операцию.
 * @returns true если retry_count < MAX_RETRIES
 */
export function shouldRetry(retryCount: number): boolean {
  return retryCount < MAX_RETRIES;
}

/**
 * Вычислить абсолютное время следующей попытки (ISO string).
 */
export function getNextRetryAt(retryCount: number): string {
  const delay = getRetryDelay(retryCount);
  return new Date(Date.now() + delay).toISOString();
}

Математика backoff

Формула

delay = min(BASE_DELAY × 2^retryCount, MAX_DELAY)
actual_delay = delay + delay × 0.2 × random(-1, 1)

Таблица задержек

Попытка Баз��вая задержка Диапазон с jitter
1 1000ms 800ms — 1200ms
2 2000ms 1600ms — 2400ms
3 4000ms 3200ms — 4800ms
4 8000ms 6400ms — 9600ms
5 16000ms 12800ms — 19200ms
6+ Операция помечается как permanently failed

Общее время до permanent failure

В худшем случае (все retry с максимальным jitter):

1200 + 2400 + 4800 + 9600 + 19200 = 37200ms ≈ 37 секунд

В лучшем с��учае (минимальный jitter):

800 + 1600 + 3200 + 6400 + 12800 = 24800ms ≈ 25 секунд

Обработка permanent failures

Когда shouldRetry() возвращает false (5 попыток исчерпаны):

  1. Операция остаётся в статусе failed навсегда
  2. Для операций DELETE — выполняется rollback:
  3. deleted_locallyfalse
  4. sync_status'synced'
  5. UI обновляется (вещь/образ снова появляется)
  6. Пользователь видит данные и может попробовать удалить позже

Почему jitter?

Без jitter при восстановлении сети все клиенты будут повторять запросы в одно время (thundering herd). Jitter ±20% распределяет нагрузк�� на сервер.

Клиент A: retry через 1100ms
Клиен�� B: retry через 850ms  
Клиент C: retry через 1190ms