Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Завершение
Чем ack, drop, retry и retry_after становятся в
ZeroMQ, где завершать нечего: ack отвечает Unsupported, а повтор - это копия, которую публикует
сервис.
Схема текстом
- Обработчик: ack(); retry(); retry_after(d); drop()
- Доставка: AckError:: Unsupported; AckError:: Unsupported; копия через d; AckError:: Unsupported
- Сообщение: готово: завершать нечего; пропадает, если предел не объявлен, иначе копия; копия - новое сообщение, попытка учтена; пропадает
- ack() → AckError:: Unsupported
- AckError:: Unsupported → готово: завершать нечего
- retry() → AckError:: Unsupported
- AckError:: Unsupported → пропадает, если предел не объявлен, иначе копия
- retry_after(d) → копия через d
- копия через d → копия - новое сообщение, попытка учтена
- drop() → AckError:: Unsupported
- AckError:: Unsupported → пропадает
- Доставка не более одного раза: сообщение, которое обработчик не закончил, повторно не доставляется
Сокет ZeroMQ передаёт сообщение и забывает о нём. В протоколе нет подтверждения, поэтому
ack и nack у ZmqMessage сразу отвечают
AckError::Unsupported. Рантайм записывает этот ответ в журнал как предупреждение, а сообщение в
любом случае считается обработанным.
Обычный retry() ничего не доставляет повторно, и обработчик второй раз не вызывается. Регистрация,
которая объявляет max_attempts или
адрес dead-letter, превращает retry() в копию, как
для retry_after.
ZeroMQ не считает доставки, поэтому redelivery_count пуст, и попытки считает сам рантайм.
Счётчик передаётся в заголовке копии x-ruststream-retry-count, и первая доставка считается
первой попыткой.
Повторы
Схема текстом
- Доставка x-ruststream-retry-count говорит, какая это попытка → Обработчик возвращает retry_after(delay) или retry() при объявленном пределе: обработана
- Обработчик возвращает retry_after(delay) или retry() при объявленном пределе → max_attempts: попытка ниже предела?: повтор
- max_attempts: попытка ниже предела? → Привязана: копия своему слушателю: ниже
- max_attempts: попытка ниже предела? → Подключена или отвечает: копия по заданному адресу
- max_attempts: попытка ниже предела? → На пределе: копия по имени dead-letter: на пределе
- max_attempts: попытка ниже предела? → На пределе, без dead-letter: отброшена
- Привязана: копия своему слушателю → Копия - новое сообщение, ещё одна попытка
- Подключена или отвечает: копия по заданному адресу → Копия - новое сообщение, ещё одна попытка
- Копия ждёт задержку внутри процесса: падение до срабатывания таймера её теряет
Исход retry_after выжидает задержку внутри процесса, а затем публикует копию через
издателя повторов регистрации. Куда уходит копия, зависит
от паттерна и от стороны конечной точки, и это выражено в типе.
Подписка ZmqQueue или
ZmqFanout, которая привязывает свою конечную точку,
сообщает своё имя в качестве адреса. Издатель повторов подключается к собственному слушателю
подписки, и копия приходит туда как следующая попытка. Точка монтирования ничего не называет.
Подписка, которая подключается, читает от узла, который только отправляет. Имя отвечающей стороны
ZmqRpc - не адрес: её издатель отправляет только по
идентичностям из запросов. Ни у той, ни у другой нет адреса для копии, поэтому точка монтирования
называет, куда уходят копии, - обычно это очередь, которую сервис привязывает для себя. Цепочка
роутера без адреса не компилируется, а регистрацию без адреса отвергает старт.
На пределе доставка уходит по адресу dead-letter через того же издателя, поэтому этот адрес принадлежит издателю на другой конечной точке. На конечной точке, которую привязывает подписка на очередь, dead-letter вернулась бы к той же подписке: издатель её не отправляет, и доставка отбрасывается. На привязанной широковещательной конечной точке имя dead-letter под префиксом подписки приходит обратно к ней. Без адреса dead-letter доставка отбрасывается с предупреждением.