Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Завершение
Чем ack, retry, drop и retry_after становятся в потоке Redis, надёжном списке, простом
списке и Pub/Sub.
Схема текстом
- Исход: ack; retry; drop
- Поток: XACK; XADD копии затем XACK; XACK
- Перехват: XACK; остаётся в PEL; XACK
- Надёжный: LREM; LPUSH, затем LREM; LREM
- Без ack: отказ; отказ; отказ
Рантайм завершает каждую доставку исходом, который
вернул её обработчик, а крейт переводит исход в подтверждение, свойственное форме. Поток
подтверждает запись командой XACK в группе подписки. Надёжный список удаляет запись из своего
списка обработки командой LREM. Простому списку и Pub/Sub подтверждать нечего, и завершение там
возвращает AckError::Unsupported. Команды завершения идут через пул, а не через клиент чтения
подписки.
Переобработка в потоке добавляет копию записи в тот же поток, а затем подтверждает оригинал. Сбой
между этими шагами оставляет дубликат, а не потерю. Подписка
с перехватом переобрабатывает запись через
список неподтверждённых записей. Она ничего не добавляет и не подтверждает, а её следующее чтение
перехватывает запись обратно, когда та простаивает min_idle, под тем же идентификатором и со
счётчиком доставок на единицу больше. Надёжный список возвращает запись в очередь, прежде чем
удалить её из списка обработки.
Переобработка с задержкой
Схема текстом
- Рантайм: XACK оригинала; Копия в памяти процесса: сбой её теряет; XADD копии, когда сработает таймер
- Очередь задержки: retry_after(delay) для записи потока; ZADD копии, затем XACK; Хранится в Redis с оценкой по сроку; Чтение забирает её: XADD обратно в поток
- Перехват: Запись остаётся в PEL; Перехвачена после min_idle
- retry_after(delay) для записи потока → XACK оригинала
- retry_after(delay) для записи потока → ZADD копии, затем XACK
- retry_after(delay) для записи потока → Запись остаётся в PEL
- XACK оригинала → Копия в памяти процесса: сбой её теряет
- Копия в памяти процесса: сбой её теряет → XADD копии, когда сработает таймер: задержка
- ZADD копии, затем XACK → Хранится в Redis с оценкой по сроку
- Хранится в Redis с оценкой по сроку → Чтение забирает её: XADD обратно в поток: срок
- Запись остаётся в 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 считают по счётчику доставок, который сервер ведёт в
списке неподтверждённых записей. Все остальные формы считают по заголовку счётчика переобработок,
который передаётся в копиях, а очередь задержки увеличивает его на каждом круге.