revise May 2020 background job articles
Build and deploy / deploy (push) Successful in 13s

This commit is contained in:
2026-07-31 11:27:15 +03:00
parent b1e9aae0c2
commit 406e60bf44
7 changed files with 717 additions and 1 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Производство редакционных партий
На 31 июля 2026 года строгий аудит проходит 82 из 358 созданных материалов. Остальные 276 не считаются «почти готовыми»: их нужно заменить, а не косметически удлинить.
На 31 июля 2026 года строгий аудит проходит 85 из 358 созданных материалов. Остальные 273 не считаются «почти готовыми»: их нужно заменить, а не косметически удлинить.
## Одна партия
+133
View File
@@ -0,0 +1,133 @@
# Май 2020 — тройное ревью автономного пакета P27 «Фоновые задачи»
Статус: **принят в publication registry 31 июля 2026 года**. Он включает
ровно три revision для стабильных slug; registry сохраняет дату и автора
базового архива:
- <code>editorial-2020-05-practice-background-jobs</code>;
- <code>editorial-2020-05-mechanism-background-jobs</code>;
- <code>editorial-2020-05-field-background-jobs</code>.
В module export нет полей <code>date</code> и <code>author</code>;
<code>articles.json</code>, standard, очередь и package config не
перезаписывались. При вызове <code>--print-revisions</code> stdout
содержит только JSON, а <code>--verify-fixture</code> запускает отдельную
детерминированную учебную фикстуру.
## Проход 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-у и сохранённый бизнес-
результат. Для одного <code>jobId</code> описаны состояния
<code>queued</code>, <code>running</code>, <code>retry_wait</code>,
<code>succeeded</code> и <code>quarantined</code>. Ack следует после
сохранения <code>resultKey</code> и terminal state. Повтор до этого момента
не считается дефектом: повторный worker должен увидеть завершённую задачу и
подтвердить новое delivery без второго effect.
Проверена и намеренно оставлена граница внешнего side effect. Детерминированный
путь <code>reports/{jobId}.csv</code> демонстрирует идемпотентность одного
экспорта; он не делает идемпотентными 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** знака |
- Во всех трёх текстах первый абзац называет конкретный симптом и его цену, а
второй очерчивает учебную границу. Далее выдержан маршрут «симптом → причина
→ проверка → действие → ограничение», без общей техлид-риторики.
- У каждой статьи есть не менее пяти смысловых разделов, таблица с
<code>caption</code>/<code>thead</code>, рисунок с самостоятельными
<code>alt</code> и <code>figcaption</code>, код или JSON-журнал,
нумерованный маршрут и четыре первичных/официальных источника.
- Практика объясняет outbox и порядок результата/ack. Механизм отделяет
delivery tag от <code>jobId</code>, вводит 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 — пройдено в пределах пакета
- <code>background-job-lifecycle-2020.svg</code> показывает вертикальный
путь от записи job/outbox к worker, сохранённому result, ack, retry и
quarantine/DLX.
- <code>background-job-retry-boundary-2020.svg</code> отделяет delivery tag
от terminal state и показывает, что временный retry ограничен, а постоянная
ошибка останавливается без requeue.
- <code>background-job-diagnosis-2020.svg</code> ведёт расследование по одному
<code>jobId</code> через запись задачи, outbox, журнал worker, resultKey и
карантин.
- Все схемы имеют <code>title</code>, <code>desc</code>,
<code>role="img"</code>, вертикальный viewBox, короткие подписи и контрастные
карточки. В них нет JavaScript, <code>foreignObject</code>, внешних 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-интеграционный тест.
Учебная фикстура <code>--verify-fixture</code> выполнила две цепочки в памяти:
временный отказ → повторная delivery → result → ack и три неуспеха →
quarantined. Она вернула три истинных условия: <code>ackAfterResult</code>,
<code>poisonStopped</code> и <code>retryWasRedelivered</code>. Фикстура не
подключалась к RabbitMQ, не проверяла AMQP frames, DLX policy, сеть, несколько
consumer, скорость или production workload.
### Фактически выполненные проверки
| Проверка | Команда | Реальный результат |
| --- | --- | --- |
| Синтаксис модуля | <code>node --check scripts/upgrade-2020-05.mjs</code> из <code>web/</code> | PASS, код 0 |
| Import-safe export и draft gate | <code>npm run audit:draft -- scripts/upgrade-2020-05.mjs</code> из <code>web/</code> | PASS: 9 385 / 10 550 / 10 484 знаков body; три slug, таблицы, figures, code, routes, sources и assets найдены |
| Учебная фикстура состояний | <code>node scripts/upgrade-2020-05.mjs --verify-fixture</code> из <code>web/</code> | PASS: `ackAfterResult`, `poisonStopped`, `retryWasRedelivered` — true |
| XML трёх схем | <code>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</code> из <code>web/</code> | 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 |
| <code>npm run build</code> | PASS, code 0, 374 статические страницы |
| Scope/self-review | PASS: в revision нет date/author, а <code>articles.json</code> не перезаписан |
Выпусковой вердикт: **тройное ревью пройдено, пакет принят к публикации**.
Registry заменяет только редакционные поля по стабильному slug. Реальный
broker, DLX policy, browser и assistive-tech не запускались и не выданы за
результат in-memory fixture или статической сборки.