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

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

Окно

Подписка с конвейером завершает доставки в окне: доставки одного чтения ставят свои побочные эффекты в очередь, и один сброс отправляет их вместе с завершениями.

Одно чтение подписки на поток с конвейером: каждая доставка ставит команду в очередь, исход сохраняет или отбрасывает её, и один сброс отправляет остальноеОдин сброс, один обменЗапись 1-0INCR в очередьack: сегментсохранёнЗапись 2-0INCR в очередьdrop: сегментотброшенЗапись 3-0INCR в очередьack: сегментсохранёнINCR для 1-0INCR для 3-0XACK 1-0 2-0 3-0При .atomic() каждый сегмент - MULTI, его команды,завершение своей доставки, затем EXEC
Схема текстом
  1. Один сброс, один обмен: INCR для 1-0; INCR для 3-0; XACK 1-0 2-0 3-0
  2. Запись 1-0 INCR в очередь → ack: сегмент сохранён
  3. ack: сегмент сохранён → INCR для 1-0
  4. Запись 2-0 INCR в очередь → drop: сегмент отброшен
  5. drop: сегмент отброшен → XACK 1-0 2-0 3-0: лишь XACK
  6. Запись 3-0 INCR в очередь → ack: сегмент сохранён
  7. ack: сегмент сохранён → INCR для 3-0
  8. При .atomic() каждый сегмент - MULTI, его команды, завершение своей доставки, затем EXEC

.pipeline() в точке монтирования открывает окно над подпиской. Каждая доставка одного чтения занимает в нём ячейку. Команды, которые её обработчик ставит в очередь через Ctx<keys::Pipeline>, попадают в сегмент ячейки: конвейер fred, открытый при первой такой команде. Ответа на команду обработчик не видит.

Исход решает судьбу сегмента: ack сохраняет его, а drop, retry и retry_after отбрасывают. Каждый исход отправляет то же завершение, что и без окна. Доставка, которую удалили, не завершив, завершения не отправляет: её сегмент отбрасывается, а запись остаётся неподтверждённой.

Окно сбрасывается, когда число завершённых доставок достигает COUNT чтения, когда незавершённых доставок не осталось или когда подписка останавливается. Сброс отправляет сохранённые сегменты в порядке их фиксации, а затем завершения этого чтения, одним конвейером через соединение пула. Завершения потока уходят одной командой XACK, а завершения надёжного списка - по одной LREM на запись. Под нагрузкой это один обмен с сервером на чтение.

.atomic() заключает каждый сегмент в MULTI и EXEC и помещает внутрь завершение самой доставки. Тогда побочные эффекты обработчика и его подтверждение вступают в силу вместе. Отката в Redis нет: команда, которая вернула ошибку внутри EXEC, оставляет остальные выполненными (транзакции). В кластере все ключи сегмента должны находиться в слоте ключа подписки.

Если сброс возвращает ошибку, поток доставок выдаёт её один раз. В формах с завершением запись, завершение которой не удалось, остаётся неподтверждённой и доставляется повторно.