Files
huncode 32e0550f4f
Build and deploy / deploy (push) Successful in 15s
revise May 2021 distributed lock articles
2026-07-31 12:37:36 +03:00

175 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Автономное тройное ревью П39 · май 2021 · «Блокировки и конкуренция»
Статус: **авторское тройное ревью пройдено, затем пакет принят независимым
редактором в выпусковой набор**. Revision-модуль содержит ровно три
стабильных slug:
- <code>editorial-2021-05-practice-distributed-locks</code>;
- <code>editorial-2021-05-mechanism-distributed-locks</code>;
- <code>editorial-2021-05-field-distributed-locks</code>.
В <code>revisions</code> нет <code>date</code>, <code>author</code> или
подключения registry. Эта авторская партия не меняла
<code>articles.json</code>, README, очередь, стандарт, package config или Git.
Созданы только пять разрешённых файлов, перечисленных внизу документа.
## Проход 1. Факты, историческая рамка и техника — пройдено
| Утверждение или решение | Первичный / официальный источник | Зафиксированная граница |
| --- | --- | --- |
| Для исторической точки мая 2021 выбрана линия <code>etcd v3.4</code>: её <code>Lock</code> возвращает key на время владения; unlock или expiry/revoke связанного lease освобождает lock | [etcd v3.4 Concurrency API Reference](https://etcd.io/docs/v3.4/dev-guide/api_concurrency_reference_v3/) | Документация описывает lock внутри etcd. Она не объявляет возвращённый key универсальным числовым fencing token для внешней базы, файла или API. |
| <code>LeaseGrant</code> получает advisory TTL, а ответ возвращает TTL, выбранный server; без keepalive lease истекает, attached keys удаляются | [etcd v3.4 API Reference](https://etcd.io/docs/v3.4/dev-guide/api_reference_v3/) | Учебные 5000 мс не являются значением TTL для etcd, не проверяют keepalive, clock drift или clock correctness. |
| Lock сам по себе advisory; sequencer передаётся получателю операции, а получатель проверяет его актуальность и может отвергнуть request | [Mike Burrows, The Chubby lock service for loosely-coupled distributed systems, OSDI 2006](https://research.google/pubs/the-chubby-lock-service-for-loosely-coupled-distributed-systems/) | Chubby — исторический первичный пример boundary, не скрытая реализация fixture и не рекомендация установить этот сервис. |
| Выбор v3.4 не заносит будущую версию в текст мая: официальный анонс v3.5 датирован 15 июня 2021 года и ретроспективно называет запуск v3.4 августом 2019 года | [Announcing etcd 3.5](https://etcd.io/blog/2021/announcing-etcd-3.5/) | Эта ссылка служит редакторской проверкой датировки; сама статья не ссылается на будущий для мая анонс и не использует API v3.5. |
<code>runDistributedLockFixture()</code> — детерминированная state machine
только на <code>Map</code> и ручном счётчике времени. В ней нет системных
часов, сети или provider client:
1. worker-A получает <code>training-lease-1</code> и token 1 на 5000 мс;
2. учебный clock переходит к 6000 мс, lease-1 помечается истёкшим, но
worker-A не считается остановленным;
3. worker-B получает <code>training-lease-2</code> и token 2;
4. защищаемый ресурс принимает write worker-B, сохраняет v2 и highest token 2;
5. поздний write worker-A с token 1 получает
<code>rejected-stale-fence</code>;
6. старый release worker-A не снимает текущий lease worker-B;
7. отдельный намеренно unsafe ресурс без fencing показывает, что token 1
перезаписал бы v2.
Проверены девять assertions: выдача первого lease/token, pause после expiry,
выдача второго lease/token, принятие v2, отказ stale v1, защита release нового
lease, сохранение v2, небезопасный контраст без fencing и работа только в
памяти. Главный технический вывод узкий: **fence помогает только когда
защищаемый ресурс сам хранит и монотонно проверяет token в своей операции
записи**. Generic lock не выдан за доказательство безопасности.
Не проверялись реальный etcd/Redis/ZooKeeper, provider SDK, cluster,
keepalive, сеть, clock synchronization, база, файловый storage, HTTP,
внешний API, нагрузка или provider SLA. Fixture не заявляет exactly-once,
отмену старого request и корректность реальных часов.
Вердикт прохода: **пройден**. Историческая версия и ограничения названы рядом
с механизмом, а модель не переносит свойства учебной Map на настоящий
провайдер.
## Проход 2. Редактура, глубина и голос М4 — пройдено
| Revision | Симптом и цена в первых двух абзацах | Главный вопрос | Объём основного текста |
| --- | --- | --- | ---: |
| Практика | worker-A останавливается дольше lease, B уже обновляет отчёт, A может поздно перезаписать v2 | Как до критической секции разделить lifecycle lease, owner, handle и resource-side fence | **10 939** знаков body |
| Механизм | поздний request получает успешный ответ после нового владельца, поэтому команда ошибочно обвиняет lock provider | Почему token обязан проверять защищаемый ресурс, а не только authority перед началом работы | **10 293** знака body |
| Полевой разбор | после v2 в лог попадает «успех» старого A; цена — ложный диагноз и повтор той же гонки | Как собрать evidence и отделить stale generation от duplicate, bad release и безусловного write | **9 857** знаков body |
- Все статьи начинают с наблюдаемого симптома и цены, затем держат маршрут
«симптом → причина → проверка → действие → ограничение».
- В каждой revision есть table с <code>caption</code>/<code>thead</code>,
figure с самостоятельными <code>alt</code>/<code>figcaption</code>, не
менее двух технических примеров, нумерованный путь, три первичных или
официальных источника и явный тестовый interleaving.
- Голос М4 / мая 2021 продолжает пакеты о транзакции, кешировании и очередях:
автор называет owner, handle, ресурсную границу и инвариант, но не
изображает себя владельцем большой distributed platform. Речь короткая и
предметная: <code>token 1 ≤ highest token 2 → reject</code>, а не
«блокировка магически защищает данные».
- Убраны опасные подмены: expiry не назван остановкой процесса; token не
назван clock; lease key не объявлен готовым fence для внешнего ресурса;
fencing не отождествлён с idempotency или exactly-once.
- Заголовки и excerpts обещают ограниченный результат: понять boundary и
проверить stale write, а не получить универсальный рецепт distributed lock.
Вердикт прохода: **пройден**. Тексты лежат в диапазоне 5 000–15 000 знаков и
развивают T-shape автора от delivery/данных к одному проверяемому контракту
конкуренции без анахронизмов и техлидской позы 2027 года.
## Проход 3. Визуал, fixture и preflight — пройдено в границах пакета
- <code>distributed-lock-lease-timeline-2021.svg</code> показывает полный
interleaving от lease-1/token 1 до reject позднего token 1. После первого
Sharp-рендера длинная нижняя подпись была разбита на две строки.
- <code>distributed-lock-fence-boundary-2021.svg</code> отделяет authority от
ресурса и показывает, где именно хранится highest token. После первого
рендера нижняя карточка получила две короткие строки и большую высоту.
- <code>distributed-lock-diagnosis-2021.svg</code> ведёт от evidence packet к
stale generation, duplicate, resource without compare и bad release. После
первого рендера перенесены длинная итоговая подпись и строка atomic compare.
- У всех трёх SVG есть <code>title</code>, <code>desc</code>,
<code>role="img"</code> и вертикальный viewBox. В исходниках нет
JavaScript, <code>foreignObject</code>, external URL или data URI; обычный
XML namespace не является внешним asset.
### Фактически выполненные проверки
Команды запускались из <code>web/</code> после финальных правок:
<pre><code>node --check scripts/upgrade-2021-05.mjs
npm run audit:draft -- scripts/upgrade-2021-05.mjs
node scripts/upgrade-2021-05.mjs --verify-fixture
xmllint --noout \
public/assets/editorial/2021/distributed-lock-lease-timeline-2021.svg \
public/assets/editorial/2021/distributed-lock-fence-boundary-2021.svg \
public/assets/editorial/2021/distributed-lock-diagnosis-2021.svg</code></pre>
| Проверка | Реальный результат |
| --- | --- |
| <code>node --check</code> | PASS, code 0 |
| Import-safe export и draft gate | PASS: итоговые **10 939 / 10 293 / 9 857** знаков body; найдены три slug, sections, tables, figures, code, routes, sources и локальные visual assets |
| In-memory fixture | PASS: все девять assertions истинны; worker-B получил token 2 после expiry A, ресурс принял v2 и отверг поздний token 1, старый release не удалил lease-B |
| <code>xmllint --noout</code> | PASS, все три SVG — корректный XML |
| SVG safety scan | PASS: нет <code>script</code>, <code>foreignObject</code>, external asset URL или raster data URI |
| Sharp mobile preflight | PASS после корректировки длинных подписей: вручную просмотрены финальные PNG **375×740**, **375×781** и **375×844**; clipping, overlap и horizontal overflow внутри схем не обнаружены |
| Scope/self-review | PASS: созданы только пять разрешённых файлов; registry, <code>articles.json</code>, README, очередь, стандарт, package config, Git и чужие untracked files не менялись |
<code>npm run audit:draft</code> завершилась с code 0. npm вывел уже
существующие предупреждения о пользовательских <code>store-dir</code>,
<code>cache-dir</code> и <code>public-hoist-pattern</code>; эти настройки не
относятся к П39 и не менялись.
Не запускались strict audit после подключения registry, production build,
browser, screen reader, CI, deployment или публикация. Static SVG preflight не
заменяет browser review, accessibility audit и integration test выбранной
инфраструктуры.
## Итог
Статус автономного этапа: **тройное авторское ревью пройдено; П39 была готова
к отдельной интеграционной приёмке**. Commit и push на этом этапе намеренно не
выполнялись.
Созданы ровно пять файлов:
1. <code>web/scripts/upgrade-2021-05.mjs</code>;
2. <code>editorial/reviews/2021-05-draft.md</code>;
3. <code>web/public/assets/editorial/2021/distributed-lock-lease-timeline-2021.svg</code>;
4. <code>web/public/assets/editorial/2021/distributed-lock-fence-boundary-2021.svg</code>;
5. <code>web/public/assets/editorial/2021/distributed-lock-diagnosis-2021.svg</code>.
## Независимая интеграционная приёмка
Основной редактор 31 июля 2026 года подключил три revision к
<code>web/data/editorial-revisions.mjs</code>, сохранив базовый
<code>articles.json</code>, даты и автора архивных записей. В registry стало
112 revision, строгий аудит проходит 121 из 358 материалов.
Независимый факт-чек уточнил одну формулировку до выпуска: в etcd v3.4
<code>LeaseGrantRequest.TTL</code> назван advisory, а
<code>LeaseGrantResponse.TTL</code> — выбранным server значением. Поэтому
слова «запрошенный TTL — минимум» заменены на точную границу API. Учебные
5000 мс не стали claim о настройке etcd. Отдельно перепроверены: lifecycle
lock key при expiry/revoke lease и Chubby-подход с advisory lock/acquisition
count, который защищаемый server сравнивает от delayed write.
| Проверка после интеграции | Реальный результат |
| --- | --- |
| Import-safe export | PASS: три revision, без <code>date</code>/<code>author</code> |
| Строгий audit трёх slug | PASS: **10 939 / 10 293 / 9 857** знаков; у каждой статьи есть figure, table и code examples |
| In-memory fixture | PASS: все 9 assertions истинны; token 2 принят, token 1 после него отклонён, старый release не снял lease-B |
| Независимый SVG review | PASS: XML и active/external asset scan прошли; три PNG 375 px просмотрены повторно, clipping, overlap и overflow не обнаружены |
| Production build | PASS: Next.js собрал 374 статические страницы |
Ни этот отчёт, ни интеграция не утверждают запуск etcd, другого provider,
cluster, базы, HTTP, browser, SDK или внешнего API.
Выпусковой вердикт: **ACCEPT**. Commit и push выполняются отдельной
публикационной операцией; Git остаётся источником её фактической записи.