Время и офлайн-очередь
Как сервер исправляет сбитые часы устройства и сколько событие может ждать отправки.
Часы телефона могут спешить на часы или стоять в 1970 году, а событие может пролежать в очереди несколько дней без сети. Сервер учитывает оба случая, если клиент передаёт время правильно.
Два времени в батче
timestampсобытия — когда событие произошло, по часам устройства;sent_atбатча — когда отправлен HTTP-запрос, по тем же часам.
Оба поля — RFC 3339 с явным смещением (Z или +03:00), лучше с миллисекундами. Строка без
смещения отклоняется с кодом invalid_field. Выставляйте sent_at заново при каждой попытке
отправки, в том числе при повторе батча. Пример досыла из терминала — в рецепте
curl.
Коррекция часов
Сервер не доверяет абсолютному времени устройства, но доверяет разнице между двумя его отметками:
event_time = received_at + (timestamp − sent_at)received_at — время приёма запроса по часам сервера. Если часы устройства спешат на 3 часа, обе
отметки сдвинуты одинаково, и разница остаётся верной.
| Ситуация | Результат |
|---|---|
event_time позже received_at больше чем на 10 минут | Событие принято с event_time = received_at и предупреждением timestamp_in_future_clamped |
event_time раньше received_at больше чем на 7 дней | Событие отклонено с кодом event_too_old |
| Ровно 7 дней | Принято: граница включительно |
Исходный timestamp сохраняется как client_time и виден в профиле.
Офлайн-очередь
Без сети события копятся на устройстве и уходят позже. Требования к очереди:
- Хранить на диске, а не в памяти: приложение могут выгрузить в фоне.
- Отправлять батчами до 500 событий и 1 МиБ, при старте приложения, при
session_startи при появлении сети. - Удалять события старше 7 дней до отправки: сервер их всё равно отклонит.
- Удалять из очереди только после ответа. Порядок действий для каждого кода ответа описан в Ошибки и повторы.
- Повторять тот же батч с теми же
insert_id. Дубликаты не завышают метрики, поэтому повтор после таймаута безопасен даже если первый запрос дошёл.
Лимит на одно устройство — 1000 событий сразу и затем 100 в минуту. Его хватает, чтобы досылать
недельную очередь. Что не уложилось в лимит, сервер вернёт в rejected с retryable: true — эти
события оставьте в очереди и отправьте через минуту.
Досыл и дни отчётов
Событие, присланное через несколько дней, попадает в тот день, когда оно произошло. Поэтому цифры
прошлых дней могут немного вырасти задним числом — в пределах окна досыла в 7 дней. Позже события
отклоняются как event_too_old, и цифры дня больше не меняются, с двумя исключениями: смена часового
пояса приложения пересчитывает все прошлые дни в новом поясе, а удаление данных человека — дни, в
которые он был активен. Оба пересчёта делает ближайшее закрытие дней, раз в 15 минут.