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

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

Завершение

Чем ack, drop, retry и retry_after становятся в NATS: подтверждением, на которое действует сервер JetStream, и копиями, которые рантайм публикует в Core.

Каждый исход обработчика на доставке JetStream: что отправляет доставка и что делает серверОбработчикОтправленоСерверack()+ACKготово,больше неотправляетсяretry()-NAKснова сразу,delivered+ 1retry_after(d)-NAK{"delay": …}ждёт d,затем снова,delivered + 1drop()+TERMпрекращено,больше неотправляетсянет исходадо ack_waitничегоснова послеack_wait,delivered + 1В Core NATS любой исход возвращает AckError::Unsupported:сервер ничего не завершает
Схема текстом
  1. Обработчик: ack(); retry(); retry_after(d); drop(); нет исхода до ack_wait
  2. Отправлено: +ACK; -NAK; -NAK {"delay": …}; +TERM; ничего; В Core NATS любой исход возвращает AckError::Unsupported: сервер ничего не завершает
  3. Сервер: готово, больше не отправляется; снова сразу, delivered + 1; ждёт d, затем снова, delivered + 1; прекращено, больше не отправляется; снова после ack_wait, delivered + 1
  4. ack() → +ACK
  5. +ACK → готово, больше не отправляется
  6. retry() → -NAK
  7. -NAK → снова сразу, delivered + 1
  8. retry_after(d) → -NAK {"delay": …}
  9. -NAK {"delay": …} → ждёт d, затем снова, delivered + 1
  10. drop() → +TERM
  11. +TERM → прекращено, больше не отправляется
  12. нет исхода до ack_wait → ничего
  13. ничего → снова после ack_wait, delivered + 1

Доставка JetStream завершается на сервере. Ответ уходит в субъект подтверждения доставки, и консьюмер поступает с ним так, как показывает страница Консьюмеры. retry_after помещает задержку в само отрицательное подтверждение. Сервер придерживает сообщение и повторно доставляет его тому же консьюмеру, с тем же номером в стриме и счётчиком delivered на единицу больше. Ничего не публикуется, и копия не создаётся.

Доставку Core завершать нечем. ack, retry и drop возвращают AckError::Unsupported, и рантайм записывает это в журнал. Сервер не хранит ничего для повторной доставки, и рантайм возвращает сообщение только копией, которую публикует сам. Это доставка at-most-once.

ИсходCore NATS
ack, dropAckError::Unsupported
retry()AckError::Unsupported; при объявленном пределе копия публикуется сразу
retry_after(d)копия публикуется через d
нет исходаничего

Переобработка​

Переобработка в NATS: предел попыток выбирает между возвратом сообщения и субъектом для недоставленныхНиже пределаНа пределеДоставкаJetStream считает доставки, в Core счёт в заголовкеОбработчик возвращаетretry_after(delay) или retry() при объявленииmax_attempts: попытка ниже предела?JetStream:-NAK с задержкой,сервер придерживаетСубъект Core:копия публикуетсяв этот субъектШаблон Core:копия в субъектиз точки монтированияСубъект длянедоставленных:доставка уходиткак пришлаБез такогосубъекта: +TERMв JetStream,ничего в CoreКопия Core ждёт задержку внутри процесса:остановка до срабатывания таймера её теряет
Схема текстом
  1. Ниже предела: JetStream: -NAK с задержкой, сервер придерживает; Субъект Core: копия публикуется в этот субъект; Шаблон Core: копия в субъект из точки монтирования
  2. На пределе: Субъект для недоставленных: доставка уходит как пришла; Без такого субъекта: +TERM в JetStream, ничего в Core
  3. Доставка JetStream считает доставки, в Core счёт в заголовке → Обработчик возвращает retry_after(delay) или retry() при объявлении: обработана
  4. Обработчик возвращает retry_after(delay) или retry() при объявлении → max_attempts: попытка ниже предела?: переобработка
  5. max_attempts: попытка ниже предела? → Ниже предела: ниже
  6. max_attempts: попытка ниже предела? → На пределе: на пределе
  7. Копия Core ждёт задержку внутри процесса: остановка до срабатывания таймера её теряет

Предел объявляется в точке монтирования через max_attempts, и первая доставка считается первой попыткой. В JetStream счёт ведёт сам сервер в своём delivered, поэтому доставка, которая не уложилась в ack_wait, тоже учитывается. В Core рантайм считает опубликованные копии в заголовке копии x-ruststream-retry-count.

Ниже предела каждая модель возвращает сообщение по-своему. JetStream повторно доставляет его из стрима. В Core рантайм публикует копию по адресу, который сообщает дескриптор. CoreSubject сообщает свой субъект. CoreWildcard подходит ко многим субъектам и не публикует ни в один из них, поэтому его регистрация называет субъект для копии, иначе приложение не запустится.

На пределе доставка уходит в субъект для недоставленных сообщений в том виде, в каком пришла: полезная нагрузка и заголовки не меняются. Если субъект для недоставленных не объявлен, доставка JetStream прекращается через +TERM, а доставку Core рантайм просто отпускает.

Крейт ничего не объявляет серверу: max_deliver остаётся незаданным, потому что у JetStream нет места, куда отправить сообщение, исчерпавшее доставки. Путь рантайма покрывает обе модели.