Skip to content

ADR 0043: подтверждение объектных сессий и completion lease ​

Статус: принято. Дополняет ADR 0042; не вводит кластерную репликацию.

Общий writer claim и объектные locks находятся на разных соединениях. Здоровье первого не доказывает здоровье остальных. StorageOwnership расширен проверками bigint object locks и liveness сессии с динамическими shared content pins. Этот инфраструктурный адаптер владеет выделенным pg-клиентом, проверяет ту же сессию каждые две секунды с deadline две секунды и локальным окном восемь секунд, никогда не переподключается внутри операции.

Upload mutations и offline GC проверяют точные объектные locks. Online GC проверяет singleton lock своей сессии; per-object locks получают и освобождают только на ней. При завершении сессия исключается из pool и закрывается. pg может выполнять graceful Terminate для idle client, поэтому transport stream уничтожается явно: иначе close может ждать удалённый FIN после partition. Это изолированное использование типизированного pg driver transport; plain/TLS поток закрывается одинаково. Дополнительная цена — новое соединение для следующей объектной операции; необходимость безопасного переиспользования оценивается отдельно по измерениям, без возврата неизвестного lock state в pool.

Content pins сохраняют reference counts. Потеря сессии делает все старые handles недействительными. Новую сессию можно открыть только после release всех handles. Ни один старый handle не получает новую защиту автоматически. Блокировки не сериализуют все скачивания и не создают по соединению на поток.

HTTP проверяет pin после асинхронного разрешения метаданных и с обеих сторон bandwidth pacing. Проверка только перед чтением недостаточна: уже прочитанный chunk может ждать полосу после потери pin. Внешний guard проверяет каждый выдаваемый quantum и завершение источника; внутренний guard сохраняет проверку перед первым чтением. HEAD/304/416 также не обходят проверку после metadata lookup. BandwidthGovernor проверяет собственное закрытие после выдачи допуска и при EOF, включая пустой источник. Это уточнение действующего протокола, без изменения HTTP схем, прав или storage backend.

PostgresJobLease оркестрирует существующие SQL heartbeat/finish с generation и expiry. Перед сборкой worker подтверждает текущую reservation, затем продлевает не более одного запроса одновременно; вместо очереди setInterval используется следующий setTimeout после ответа. Локальное окно 8 секунд консервативнее SQL reservation 30 секунд. Потерянный/просроченный grant не возрождается; false от finish не считается завершённой job. Проверка локальных часов детерминированно покрыта тестом с задержанным renewal.

Worker наблюдает process ownership и активный job lease независимо от файлового I/O. Потеря инициирует AbortSignal, код завершения 1 и предельное ожидание остановки 120 секунд; SIGINT/SIGTERM используют тот же ограниченный drain. Принудительное завершение не делает неподтверждённый blob опубликованным: следующий worker повторяет completion по прежнему протоколу.

Граница остаётся прежней: runtime не может атомарно отменить уже отправленную файловую операцию, удалить уже буферизованные сетевые байты или оградить две независимые PostgreSQL primary. API-адаптеры метаданных используют другие SQL-сессии; глобального DB fencing token для каждой mutation не добавлено. Переключение физического узла требует внешнего fencing и выбранного backend. Реестр дефектов и оставшихся требований: CLUSTER_AUDIT_2026-09-26.

Arkvory · ProAnimaStudio