Перейти к основному содержимому
Нормативная версия документации - английская

Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.

Завершение

Чем ack, retry, drop и retry_after становятся в потоке Redis, надёжном списке, простом списке и Pub/Sub.

Команды, которые отправляет каждый исход в каждой форме: поток, поток с перехватом, надёжный список и формы без подтвержденияИсходПотокПерехватНадёжныйБез ackackXACKXACKLREMотказretryXADD копиизатем XACKостаётсяв PELLPUSH,затем LREMотказdropXACKXACKLREMотказ
Схема текстом
  1. Исход: ack; retry; drop
  2. Поток: XACK; XADD копии затем XACK; XACK
  3. Перехват: XACK; остаётся в PEL; XACK
  4. Надёжный: LREM; LPUSH, затем LREM; LREM
  5. Без ack: отказ; отказ; отказ

Рантайм завершает каждую доставку исходом, который вернул её обработчик, а крейт переводит исход в подтверждение, свойственное форме. Поток подтверждает запись командой XACK в группе подписки. Надёжный список удаляет запись из своего списка обработки командой LREM. Простому списку и Pub/Sub подтверждать нечего, и завершение там возвращает AckError::Unsupported. Команды завершения идут через пул, а не через клиент чтения подписки.

Переобработка в потоке добавляет копию записи в тот же поток, а затем подтверждает оригинал. Сбой между этими шагами оставляет дубликат, а не потерю. Подписка с перехватом переобрабатывает запись через список неподтверждённых записей. Она ничего не добавляет и не подтверждает, а её следующее чтение перехватывает запись обратно, когда та простаивает min_idle, под тем же идентификатором и со счётчиком доставок на единицу больше. Надёжный список возвращает запись в очередь, прежде чем удалить её из списка обработки.

Переобработка с задержкой​

Три способа, которыми подписка на поток выполняет retry_after: копия в процессе, копия в упорядоченном множестве Redis или запись, оставленная неподтверждённойРантаймОчередь задержкиПерехватretry_after(delay) для записи потокаXACKоригиналаКопия в памятипроцесса:сбой её теряетXADD копии,когда сработаеттаймерZADD копии,затем XACKХранится в Redisс оценкойпо срокуЧтение забираетеё: XADD обратнов потокЗаписьостаётсяв PELПерехваченапослеmin_idle
Схема текстом
  1. Рантайм: XACK оригинала; Копия в памяти процесса: сбой её теряет; XADD копии, когда сработает таймер
  2. Очередь задержки: retry_after(delay) для записи потока; ZADD копии, затем XACK; Хранится в Redis с оценкой по сроку; Чтение забирает её: XADD обратно в поток
  3. Перехват: Запись остаётся в PEL; Перехвачена после min_idle
  4. retry_after(delay) для записи потока → XACK оригинала
  5. retry_after(delay) для записи потока → ZADD копии, затем XACK
  6. retry_after(delay) для записи потока → Запись остаётся в PEL
  7. XACK оригинала → Копия в памяти процесса: сбой её теряет
  8. Копия в памяти процесса: сбой её теряет → XADD копии, когда сработает таймер: задержка
  9. ZADD копии, затем XACK → Хранится в Redis с оценкой по сроку
  10. Хранится в Redis с оценкой по сроку → Чтение забирает её: XADD обратно в поток: срок
  11. Запись остаётся в PEL → Перехвачена после min_idle: простой

В Redis нет задержки для отдельной записи, поэтому подписка на поток выполняет retry_after одним из трёх способов. По умолчанию рантайм подтверждает оригинал и держит копию, которую публикует обратно в поток, когда истекает задержка. Счётчик переобработок у копии на единицу больше. Сбой до срабатывания таймера копию теряет.

delayed_retry с DelayedRetry::DurableZset хранит копию в Redis. Копия добавляется в упорядоченное множество с оценкой, равной её сроку, а затем оригинал подтверждается. Каждое чтение сначала возвращает в поток командой XADD копии, срок которых наступил, не больше 128 за чтение, поэтому задержка соблюдается с точностью до одного интервала block. Оценки - миллисекунды системных часов, поэтому часы сервисов, которые делят одну очередь, должны совпадать.

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

Подписка на список и подписка Pub/Sub используют копию рантайма, которая возвращается в список или в канал. Подписка по шаблону задаёт адрес своих копий в точке монтирования.

Предел max_attempts считает попытки по одному из двух счётчиков, а по какому именно, зависит от формы подписки. Режимы claiming и reclaim считают по счётчику доставок, который сервер ведёт в списке неподтверждённых записей. Все остальные формы считают по заголовку счётчика переобработок, который передаётся в копиях, а очередь задержки увеличивает его на каждом круге.