# Май 2020 — тройное ревью автономного пакета P27 «Фоновые задачи» Статус: **принят в publication registry 31 июля 2026 года**. Он включает ровно три revision для стабильных slug; registry сохраняет дату и автора базового архива: - editorial-2020-05-practice-background-jobs; - editorial-2020-05-mechanism-background-jobs; - editorial-2020-05-field-background-jobs. В module export нет полей date и author; articles.json, standard, очередь и package config не перезаписывались. При вызове --print-revisions stdout содержит только JSON, а --verify-fixture запускает отдельную детерминированную учебную фикстуру. ## Проход 1. Факты, состояния и границы механизма — пройдено | Утверждение | Первичный или официальный источник | Редакторская граница | | --- | --- | --- | | Delivery tag относится к доставке, а `basic.ack` и `basic.reject` относятся к этой доставке | [AMQP 0-9-1 specification](https://www.rabbitmq.com/resources/specs/amqp-xml-doc0-9-1.pdf) | Тексты не используют delivery tag как вечный идентификатор задачи и не приписывают абстрактному псевдокоду API конкретной Node-библиотеки. | | Неподтверждённая ручная delivery возвращается после закрытия канала/соединения; requeue может образовать дорогой loop | [RabbitMQ: Consumer Acknowledgements and Publisher Confirms](https://www.rabbitmq.com/docs/3.13/confirms) | `redelivered` используется как сигнал в журнале, но идемпотентность опирается на `jobId` и terminal state, а не на один флаг. | | Publisher/consumer неопределённость допускает duplicate, поэтому consumer должен быть идемпотентен либо делать deduplication | [RabbitMQ: Reliability guide](https://www.rabbitmq.com/docs/reliability) | Материалы утверждают только at-least-once контракт одной задачи; exactly-once не обещается. | | `reject`/`nack` без requeue может направить сообщение в dead-letter route при настроенном DLX | [RabbitMQ: Dead Letter Exchanges](https://www.rabbitmq.com/docs/next/dlx) | Карантин описан как проверяемый маршрут конкретной конфигурации. Не заявлено, что он существует без настройки или одинаково работает у любого broker. | Внутри статей разделены четыре факта, которые часто смешивают: запись намерения в базе, outbox-публикация, delivery worker-у и сохранённый бизнес- результат. Для одного jobId описаны состояния queued, running, retry_wait, succeeded и quarantined. Ack следует после сохранения resultKey и terminal state. Повтор до этого момента не считается дефектом: повторный worker должен увидеть завершённую задачу и подтвердить новое delivery без второго effect. Проверена и намеренно оставлена граница внешнего side effect. Детерминированный путь reports/{jobId}.csv демонстрирует идемпотентность одного экспорта; он не делает идемпотентными email, платёж, сторонний API или любое другое необратимое действие. Для него нужен собственный стабильный ключ и контракт принимающей стороны. Outbox также не выдан за распределённую транзакцию с broker: он оставляет приложению восстанавливаемую запись на публикацию, а реальный confirm зависит от выбранного клиента и стенда. Историческая граница сохранена: это М3 / май 2020. Автор уже связывает backend и delivery — состояние задачи, outbox, worker, retry и журнал — но не приписывает себе платформу observability, современную оркестрацию или универсальную реализацию задержанных очередей. Современная официальная документация использована для сверки смысла протокольных операций, а не как заявление о конкретно запущенной инфраструктуре мая 2020 года. Вердикт прохода: **пройден**. Механизм и его технологические допущения разделены; учебная фикстура не выдана за реальный broker. ## Проход 2. Редактура, глубина и голос М3 — пройдено | Ревизия | Проблема и цена в первых двух абзацах | Практический вопрос | Объём по publication draft gate | | --- | --- | --- | --- | | Практика | Экспорт исчезает или создаёт дубль; цена — потерянная работа, неверный статус и ручной разбор | Как зафиксировать намерение, outbox, result и ack в одном коротком контракте | **9 385** знаков | | Механизм | Команда смешивает job и delivery; цена — ранний ack, дубль effect или бесконечный requeue | Почему ack ставится после результата и как один `jobId` переживает повтор | **10 550** знаков | | Полевой разбор | Один экспорт дублируется, невалидная задача крутится; цена — лишний effect, перегруженный worker и скрытая причина | Как расследовать один `jobId` и остановить poison message | **10 484** знака | - Во всех трёх текстах первый абзац называет конкретный симптом и его цену, а второй очерчивает учебную границу. Далее выдержан маршрут «симптом → причина → проверка → действие → ограничение», без общей техлид-риторики. - У каждой статьи есть не менее пяти смысловых разделов, таблица с caption/thead, рисунок с самостоятельными alt и figcaption, код или JSON-журнал, нумерованный маршрут и четыре первичных/официальных источника. - Практика объясняет outbox и порядок результата/ack. Механизм отделяет delivery tag от jobId, вводит retry-политику и quarantine. Полевой текст не притворяется реальным incident: все ID, журналы и результат маркированы как анонимизированная фикстура. - Никакой текст не предлагает «повторить всё» или «увеличить timeout» без классификации. Временная, неопределённая внешняя и постоянная ошибка имеют разные проверки и разные следующие действия. Отдельный редакторский контроль подтвердил, что исходные названия заметно конкретизированы: в заголовках и excerpts есть job, worker, ack, retry, идемпотентность и poison message, а не яркий общий заголовок с коротким содержимым. Диапазон 5 000–15 000 соблюдён собственным guard модуля без таблиц, code blocks и figures; строгий draft gate дополнительно измерил видимое тело с этими артефактами. Вердикт прохода: **пройден**. Глубина достигнута через разбор границ и проверяемый маршрут, голос остаётся прагматичным уровнем М3. ## Проход 3. Визуал, фикстура и выпусковой preflight — пройдено в пределах пакета - background-job-lifecycle-2020.svg показывает вертикальный путь от записи job/outbox к worker, сохранённому result, ack, retry и quarantine/DLX. - background-job-retry-boundary-2020.svg отделяет delivery tag от terminal state и показывает, что временный retry ограничен, а постоянная ошибка останавливается без requeue. - background-job-diagnosis-2020.svg ведёт расследование по одному jobId через запись задачи, outbox, журнал worker, resultKey и карантин. - Все схемы имеют title, desc, role="img", вертикальный viewBox, короткие подписи и контрастные карточки. В них нет JavaScript, foreignObject, внешних URL или raster data URI. - Независимый mobile preflight отрендерил каждый SVG через Sharp в PNG шириной 375 px и просмотрел результат. На первом рисунке длинная последняя подпись была развёрнута в две строки, на втором короткая tag-подпись была сокращена; после правки обрезания, наложения и горизонтального выхода в SVG не осталось. Это статическая проверка visual asset, не browser-run и не тест screen reader. - Основной редактор отдельно просмотрел финальные raster-версии на 375 px и подтвердил вывод. После подключения registry strict audit и production build пройдены; они не подменяют настоящий broker-интеграционный тест. Учебная фикстура --verify-fixture выполнила две цепочки в памяти: временный отказ → повторная delivery → result → ack и три неуспеха → quarantined. Она вернула три истинных условия: ackAfterResult, poisonStopped и retryWasRedelivered. Фикстура не подключалась к RabbitMQ, не проверяла AMQP frames, DLX policy, сеть, несколько consumer, скорость или production workload. ### Фактически выполненные проверки | Проверка | Команда | Реальный результат | | --- | --- | --- | | Синтаксис модуля | node --check scripts/upgrade-2020-05.mjs из web/ | PASS, код 0 | | Import-safe export и draft gate | npm run audit:draft -- scripts/upgrade-2020-05.mjs из web/ | PASS: 9 385 / 10 550 / 10 484 знаков body; три slug, таблицы, figures, code, routes, sources и assets найдены | | Учебная фикстура состояний | node scripts/upgrade-2020-05.mjs --verify-fixture из web/ | PASS: `ackAfterResult`, `poisonStopped`, `retryWasRedelivered` — true | | XML трёх схем | xmllint --noout public/assets/editorial/2020/background-job-lifecycle-2020.svg public/assets/editorial/2020/background-job-retry-boundary-2020.svg public/assets/editorial/2020/background-job-diagnosis-2020.svg из web/ | PASS, код 0 | | Mobile visual preflight | Sharp render трёх SVG в PNG шириной 375 px и ручной просмотр | PASS после точечной правки двух коротких подписей; нет clipping, наложения или horizontal overflow внутри SVG | | Strict audit после подключения registry | PASS: 9 385 / 10 550 / 10 484 знаков; 2 / 2 / 2 table и 1 / 2 / 2 code example | | npm run build | PASS, code 0, 374 статические страницы | | Scope/self-review | PASS: в revision нет date/author, а articles.json не перезаписан | Выпусковой вердикт: **тройное ревью пройдено, пакет принят к публикации**. Registry заменяет только редакционные поля по стабильному slug. Реальный broker, DLX policy, browser и assistive-tech не запускались и не выданы за результат in-memory fixture или статической сборки.