Синхронизация при восстановлении связи

Синхронизация при восстановлении сетевого соединения в TanStack Query представляет собой один из ключевых механизмов обеспечения согласованности данных в приложениях, работающих с нестабильной сетью или офлайн-режимом. Поведение библиотеки в момент перехода из состояния offline в online строится вокруг автоматического переисполнения отложенных запросов, инвалидированных кэшей и стратегий повторной валидации, что позволяет восстановить актуальность данных без ручного вмешательства.

TanStack Query опирается на внутренний механизм отслеживания состояния сети через события браузера online и offline. При изменении статуса активируется процесс синхронизации, в рамках которого происходит переработка очередей запросов и пересчёт состояния кэша.

Основной источник сигнала:

  • window.addEventListener('online', handler)
  • window.addEventListener('offline', handler)

При переходе в online-режим библиотека инициирует повторную проверку всех активных query, которые были помечены как устаревшие или неуспешные в период отсутствия соединения.

Ключевое свойство этого механизма заключается в том, что он не требует ручного вызова refetch для большинства стандартных сценариев. Синхронизация происходит автоматически, но подчиняется внутренним правилам staleTime, cacheTime и настройкам retry.

Поведение запросов, созданных в офлайн-режиме

Когда запрос выполняется при отсутствии сети, TanStack Query переводит его в состояние error или paused, в зависимости от конфигурации и используемого fetcher’а.

Типичные сценарии:

  • запрос завершился ошибкой из-за отсутствия сети;
  • запрос был отложен через networkMode: 'offlineFirst';
  • запрос находится в состоянии ожидания повторной попытки.

После восстановления соединения такие запросы попадают в очередь на повторное выполнение. При этом библиотека сохраняет оригинальные параметры запроса, включая queryKey, что гарантирует идентичность результата при повторном выполнении.

Очередь повторного выполнения

Внутренний механизм синхронизации формирует очередь задач, которые необходимо выполнить после восстановления сети. Эта очередь включает:

  • запросы, завершившиеся ошибкой network error;
  • отложенные mutation;
  • активные queries с включённым refetchOnReconnect;
  • invalidated queries, ожидающие повторной загрузки.

Повторное выполнение происходит с учётом политики retry. Если запрос ранее достиг максимального числа попыток, он не будет автоматически перезапущен без дополнительного взаимодействия.

Поведение stale-кэша при восстановлении соединения

Состояние stale играет центральную роль в синхронизации. После возвращения сети TanStack Query оценивает каждый query:

  • если данные staleTime истёк, выполняется refetch;
  • если staleTime не истёк, но включён refetchOnReconnect, запрос всё равно обновляется;
  • если данные свежие, повторная загрузка не производится.

Таким образом, восстановление соединения не означает автоматическую перезагрузку всех данных, а лишь тех, которые соответствуют условиям устаревания или явно требуют обновления.

Опция refetchOnReconnect

Поведение синхронизации можно управлять через параметр refetchOnReconnect, который может принимать значения:

  • true — запросы автоматически обновляются при восстановлении сети;
  • false — синхронизация при reconnect отключена;
  • 'always' — принудительное обновление независимо от staleTime.

Этот параметр может быть задан как глобально через QueryClient, так и локально для конкретного запроса.

Глобальная конфигурация:

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnReconnect: true,
    },
  },
});

Локальная конфигурация:

useQuery({
  queryKey: ['profile'],
  queryFn: fetchProfile,
  refetchOnReconnect: false,
});

Поведение mutation при восстановлении сети

Mutations в TanStack Query имеют отдельный механизм обработки offline-сценариев. При отсутствии сети mutation может быть:

  • немедленно завершён с ошибкой;
  • поставлен в очередь (при использовании persist-решений);
  • отложен до восстановления соединения.

После появления сети происходит последовательное выполнение накопленных mutation. Порядок выполнения соответствует порядку добавления, что важно для сохранения консистентности состояния.

При этом каждый mutation повторно вызывает mutationFn, используя сохранённые variables. Если mutation не идемпотентен, это может привести к повторным побочным эффектам, что требует отдельной архитектурной обработки на уровне API.

Инвалидация и повторная синхронизация данных

Инвалидация кэша (invalidateQueries) тесно связана с восстановлением сети. Если query был инвалидирован в офлайн-режиме, то после reconnection он автоматически попадает в список на refetch.

Механизм работает следующим образом:

  1. query помечается как stale через invalidateQueries;
  2. при отсутствии сети refetch откладывается;
  3. после перехода в online выполняется проверка stale-статуса;
  4. query перезапрашивается, если условия соблюдены.

Это позволяет гарантировать, что любые изменения состояния, произошедшие в офлайн-режиме, будут корректно синхронизированы с сервером.

Поведение refetchOnWindowFocus в контексте reconnect

События восстановления сети часто пересекаются с фокусировкой окна. TanStack Query обрабатывает эти события независимо, но их комбинация может приводить к двойным refetch-запросам.

Приоритет логики:

  • reconnect-trigger имеет более высокий приоритет, чем window focus;
  • если reconnect уже вызвал refetch, повторный refetch по focus может быть подавлен через дедупликацию запросов;
  • dedupingInterval предотвращает повторное выполнение идентичных запросов.

Дедупликация при массовом восстановлении соединения

При резком восстановлении сети (например, после переключения Wi-Fi) может возникнуть ситуация массового запуска refetch. TanStack Query применяет механизм дедупликации:

  • одинаковые queryKey выполняются один раз;
  • параллельные запросы объединяются;
  • повторные вызовы игнорируются в пределах dedupingInterval.

Это снижает нагрузку на сервер и предотвращает лавинообразный рост сетевых запросов.

Синхронизация в режиме paused queries

В некоторых конфигурациях, особенно при использовании networkMode: 'offlineFirst', запросы могут находиться в состоянии paused. Это означает, что fetchFn не выполняется до появления сети.

После восстановления соединения такие запросы автоматически переходят в состояние active и запускаются без дополнительного триггера. При этом сохраняется контекст выполнения, включая параметры запроса и состояние предыдущих попыток.

Влияние persist-слоя на восстановление данных

При использовании persist-плагинов (например, persistence middleware) процесс синхронизации усложняется, так как данные восстанавливаются из storage перед сетевой синхронизацией.

Последовательность:

  1. восстановление кэша из storage;
  2. определение stale-состояния;
  3. запуск reconnect-события;
  4. выполнение refetch для устаревших данных;
  5. синхронизация mutation queue.

Такой подход позволяет обеспечить почти мгновенное восстановление UI с последующей актуализацией данных.

Конфликты данных при асинхронной синхронизации

При восстановлении сети возможны конфликты между локальными изменениями и серверным состоянием. TanStack Query не решает конфликт автоматически, но предоставляет инструменты:

  • optimistic updates через onMutate;
  • rollback через onError;
  • ручная синхронизация через setQueryData.

Типичная проблема возникает, когда mutation выполняется после восстановления сети, но до завершения refetch queries. В таких случаях порядок выполнения mutation и query refetch становится критическим фактором.

Поведение в условиях нестабильной сети

При частых переключениях online/offline система синхронизации может входить в цикл повторных попыток. Для стабилизации поведения используются:

  • retryDelay с экспоненциальной задержкой;
  • ограничение retry;
  • отключение refetchOnReconnect для части запросов;
  • разделение критичных и некритичных данных по queryKey.

Такой подход предотвращает перегрузку сети и избыточные обновления кэша.

Контроль синхронизации через QueryClient

QueryClient выступает центральным координатором процесса восстановления соединения. Он агрегирует события сети и управляет глобальными стратегиями:

  • какие query должны обновляться;
  • какие mutation следует повторить;
  • какие запросы остаются в кеше без изменений.

Через QueryClient можно реализовать кастомные стратегии синхронизации, например:

  • приоритетное обновление критичных данных;
  • отложенное обновление второстепенных ресурсов;
  • ручная блокировка синхронизации в определённых состояниях приложения.

Итоговое поведение системы синхронизации

Механизм восстановления соединения в TanStack Query представляет собой многоуровневую систему, объединяющую события сети, состояние кэша, очереди mutation и стратегию повторных запросов. Он обеспечивает автоматическое восстановление актуальности данных при минимальном участии разработчика, сохраняя при этом гибкость управления через конфигурационные параметры и ручные методы контроля.