Перейти к содержанию

Асинхронный оракул: ID запроса и запоздалый ответ

Внешняя проверка выпуска выполняется асинхронно. Между началом и ответом редактор может открыть другой курс, обновить материалы или повторить запрос после задержки. Чтобы результат не попал в чужую карточку, библиотеке нужна точная идентичность задания, независимая от текущего экрана.

Продолжим современную модель отдельного ReleaseCheckRegistry. Она не является новым методом CourseCatalog и не зависит от снятого Functions. Результат урока — журнал намерения, выполнения и ответа с правилами поздней доставки. Реальных workflow и внешних запросов нет.

Намерение и внешняя идентичность

До отправки библиотека создаёт своё намерение проверить определённый выпуск. Оно связывает courseId 17, редакцию, SHA-256 точных байтов манифеста, назначение проверки и версию схемы. Такой объект существует даже тогда, когда внешний сервис ещё не вернул идентификатор выполнения.

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

{
  "jobId": "library-check-edition-2",
  "courseId": "17",
  "edition": "2",
  "manifestDigest": "EXPECTED_SHA256",
  "purpose": "release-format-check",
  "state": "prepared",
  "attempts": []
}

Это прикладная запись с меткой digest, не результат исполнения. Читатель не принимает её за действительный подписанный report. При будущем запуске фактический идентификатор сохраняется после получения по выбранному адаптеру.

Привязка ответа

Ответ сопоставляется с конкретным выполнением и его исходным намерением. Затем сверяются назначение, редакция и ожидаемый манифест. Совпадение courseId недостаточно: один курс имеет множество выпусков и проверок. Если сервер хранит только «последний запрос курса», поздний ответ способен заменить результат нового задания.

Подлинность маршрута устанавливается отдельной границей. Произвольный посетитель не получает право прислать jobId и объявить проверку успешной. После доверенного получения данные всё равно должны иметь поддерживаемую схему и соответствующее назначение. Идентичность сама по себе не доказывает качество результата.

Для интерфейса операция также хранит снимок выбранной цели. Если страница уже открыла другой выпуск, поздний обработчик не переписывает его статус. Можно обновить архивную карточку того задания, которому действительно принадлежит ответ.

Неизвестный результат отправки

Сервис принял запрос, а соединение прервалось до возвращения идентификатора. Локальный процесс не знает, создано ли внешнее выполнение. Это состояние отличается от подтверждённого отказа. Автоматическое повторение может дать две попытки одной проверки.

Адаптер использует документированную возможность сверки по собственной корреляции, известному событию или ресурсу, если такая возможность есть. Если внешняя идемпотентность не предусмотрена, собственный jobId не создаёт её магически. Тогда политика сохраняет неопределённость и учитывает возможный дубль при принятии результата.

Если обнаружены две попытки, журнал их не объединяет в выдуманное одно выполнение. Он связывает обе с намерением и применяет предусмотренное правило: какой ответ допускается, когда решение завершено и что делать с повтором.

Тайм-аут и поздний ответ

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

Для нашей проверки формата можно сохранить поздний результат как наблюдение, не менять новую текущую редакцию и показать, когда он получен. Если результат должен запускать необратимое действие, правило требует более строгой связи с актуальным назначением. Один общий callback не должен превращать любую позднюю запись в разрешение публикации.

Отмена внешнего ресурса, если сервис её поддерживает, имеет свой результат. Нажатие кнопки «отмена» на странице не доказывает, что уже начавшийся процесс остановлен. Журнал сохраняет намерение отмены и фактическое подтверждение раздельно.

Повтор успешного ответа

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

Если выполнение уже завершено положительным статусом, другой ответ с тем же идентификатором и несовместимым содержанием является конфликтом. Нельзя бесшумно выбрать последнее сообщение. Сохраняется источник и причина исследования; итоговое состояние не переопределяется произвольным порядком HTTP-доставки.

При этом одинаковые ответы разных попыток могут быть ожидаемым следствием повторения. Их транспортная уникальность и бизнес-назначение различаются. Для нашей библиотеки одну редакцию объявляет publisher по своему договору; проверочный журнал предоставляет отдельные основания, а не автоматически повторяет издательское действие.

Два выпуска одновременно

Редакция 2 проходит проверку, затем автор подготовил редакцию 3. Ответ для второй пришёл после того, как текущая карточка переключена на третью. Правильное поведение — обновить именно задание второй, сохранив третью незавершённой до её собственного результата. Внешне похожее название курса не оправдывает перенос ответа.

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

Для оператора полезна таблица активных заданий с их редакциями и стадиями. Она показывает задержки без необходимости повторно публиковать материалы. Архив исходных манифестов позволяет позднее объяснить, что именно проверялось.

Идентификатор также имеет область сервиса и конфигурации. Два независимых исполнителя могут выдать похожие локальные значения, не обозначающие одно выполнение. Поэтому ключ корреляции не строится из одного короткого номера без контекста. Версия workflow, сеть consumer и назначение сохраняются рядом. Если среда мигрировала, старый внешний номер не становится идентичностью нового запуска. Такая запись позволяет восстановить журнал после смены поставщика, сохранив точную связь исторического ответа с первоначальным намерением библиотеки.

Подготовленная последовательность

Сохраним стадии prepared, submitted, observed, accepted, rejected и expired как собственные категории, а внешние статусы — рядом. Переходы имеют причины и идентичность попытки. Все эти названия являются проектируемой моделью, а не выданными за наблюдение логами CRE.

Понятия workflow и report описаны в CRE key terms, граница приёма — в consumer contracts. Следующая глава определит схему ответа: правильная корреляция не делает произвольную строку пригодным результатом.

Оглавление серии