Синхронизация данных после возвращения сети
Пользователь оффлайн отметил 50 операций. Сеть вернулась. Как отправить всё в правильном порядке и не потерять.
Локальное хранение действий — половина задачи. Вторая — корректно отправить их когда сеть вернётся. Тут много граблей.
Структура очереди
- Каждое действие в IndexedDB как отдельная запись с полями: id, type, payload, createdAt, retries, status
- Status: pending → sending → done или failed
- Сортировка по createdAt — отправляем в порядке создания
Когда отправлять
- Background Sync API — браузер сам разбудит SW когда сеть появится. Поддержка только в Chrome/Edge на 2026
- Online event — `window.addEventListener('online', flush)` — работает везде, но ловит только переход offline→online
- Periodic check — каждые 30 секунд пробуем отправить, если есть pending. Старая школа, надёжно
- Лучшее — комбинация: Background Sync где есть, online event как fallback, periodic check как safety net
Retry logic
- Exponential backoff: 1s, 2s, 4s, 8s — но не больше 5 минут
- Maximum retries: 5-10 попыток. После — пометить как failed, показать UI
- Сетевые ошибки — retry. 4xx ответы (401, 403, 404, 422) — не retry, сразу failed
- 5xx ответы — retry с увеличением задержки
Конфликты
Самое сложное. Два пользователя оффлайн-исправили одну запись. Что делать:
- Last-write-wins — побеждает последнее изменение. Простое, но теряются данные
- Optimistic locking — у каждой записи есть version. Сервер отвергает, если version старее текущей. UI просит решить конфликт
- CRDT — структуры данных, которые мерджатся автоматически. Сложно, но для совместного редактирования — единственный путь
UI
- Бейдж счётчика непросинхронизированных в углу экрана
- Тап → список действий с возможностью retry или delete
- При неуспехе после всех retry — нотификация с действиями