Conventional commits / commits (pull_request) Successful in 10s
Specs security / security (pull_request) Successful in 8s
Specs verify / verify (pull_request) Successful in 9s
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 11s
115 lines
8.9 KiB
Markdown
115 lines
8.9 KiB
Markdown
# Proposal
|
|
|
|
## Why
|
|
|
|
Почасовая синхронизация T-Bank может завершиться в неконсистентном состоянии
|
|
после ошибки сохранения: незавершённая попытка записывается как полный успех,
|
|
ошибка финализации либо подавленная ошибка закрытия оставляет попытку в
|
|
состоянии выполнения навсегда, а локальная reservation не позволяет запустить
|
|
следующий обход в том же процессе. Пользователь видит ложный успех и перестаёт
|
|
получать обновления до перезапуска backend, а неудавшееся ожидание дочерних
|
|
шагов может ждать без ограничения. Механизм подтверждён статически (BE-002,
|
|
BE-015, RISK-001, RISK-002, TQ-003); частота проявления в production пока не
|
|
установлена.
|
|
|
|
## What Changes
|
|
|
|
- Итог попытки определяется фактическим результатом каждого обязательного шага:
|
|
невыполненный шаг даёт частичный успех либо неуспех, но не полный успех, а
|
|
уже полученные успехи отдельных счетов и разделов сохраняются.
|
|
- Прерванная попытка (ошибка, сбой сохранения, остановка процесса, истечение
|
|
ожидания) обозначается частичным успехом либо неуспехом и не получает нового
|
|
публичного состояния; причина прерывания фиксируется существующим
|
|
диагностическим полём.
|
|
- Попытка достигает итога в ограниченное время: ожидание дочернего шага
|
|
ограничено, а зависшая попытка не остаётся в выполнении бесконечно.
|
|
- Состояние в SQLite восстанавливается после сбоя сохранения: брошенная попытка
|
|
закрывается диагностируемым итогом, ожидание завершается, следующая
|
|
допустимая попытка может стартовать без перезапуска процесса.
|
|
- Восстановление не создаёт перекрытия обходов и не принимает устаревшие
|
|
результаты: поздняя публикация относительно актуального преемника
|
|
отклоняется.
|
|
|
|
## Scope
|
|
|
|
### In Scope
|
|
|
|
- Итоговый статус попытки часового обхода и обработка ошибок в дочерних
|
|
финализаторах.
|
|
- Ограниченное ожидание дочерних шагов и восстановление после ошибок
|
|
завершения шага, публикации результата и закрытия попытки.
|
|
- Защита от перекрытия обходов и от поздней публикации устаревших данных при
|
|
восстановлении.
|
|
- Контролируемая остановка и перезапуск процесса и их влияние на незавершённую
|
|
попытку, подтверждённые тестами.
|
|
- Наблюдаемый результат попытки: время начала, состояние, безопасный перечень
|
|
проблемных счетов и разделов.
|
|
|
|
### Out of Scope / Non-Goals
|
|
|
|
- Распределённая очередь, lease, поддержка нескольких реплик и изменение
|
|
топологии deployment.
|
|
- Удаление данных.
|
|
- Ослабление существующих ограничений CAS для попытки, ревизии подключения и
|
|
источника данных.
|
|
- Новый публичный статус попытки и изменения HTTP contract.
|
|
- Новый параллельный scheduler или замена владельцев строк синхронизации.
|
|
- Проверка часовой cadence и cleanup workflow — независимые задачи.
|
|
|
|
## Capabilities
|
|
|
|
### New Capabilities
|
|
|
|
- Нет.
|
|
|
|
### Modified Capabilities
|
|
|
|
- `hourly-investment-sync`: итог попытки из фактических результатов шагов,
|
|
ограниченное ожидание шага, диагностируемое закрытие брошенной попытки,
|
|
отсутствие перекрытий и устаревшей публикации.
|
|
|
|
## Impact
|
|
|
|
- **Пользователь**: достоверный статус последнего обхода вместо ложного успеха
|
|
и бесконечного «выполняется» после сбоя сохранения; обновления продолжаются
|
|
без перезапуска процесса.
|
|
- **Backend**: координатор часового обхода, дочерние финализаторы обновления
|
|
данных и reservation попытки в SQLite.
|
|
- **Frontend**: не затрагивается — наблюдаемый словарь состояний и форма
|
|
ответов не меняются.
|
|
- **Внешняя система T-Bank**: contract не меняется; начатые запросы к T-Bank
|
|
могут завершаться поздно и должны корректно отклоняться как устаревшие.
|
|
- **Процессы**: диагностика причин прерывания попыток и восстановление после
|
|
ошибок сохранения.
|
|
|
|
## Success Criteria
|
|
|
|
- Попытка с невыполненным обязательным шагом никогда не наблюдается как полный
|
|
успех; частичные успехи счетов и разделов остаются видимыми.
|
|
- После однократной ошибки завершения шага, публикации результата либо закрытия
|
|
попытки и последующего восстановления ожидание завершается, а следующая
|
|
допустимая попытка стартует.
|
|
- Устаревшая попытка наблюдается относительно актуального преемника; поздняя
|
|
публикация старого процесса отклоняется и не меняет данные.
|
|
- Координатор различает состояния `first`, `not-due`, `running`, `restart` и
|
|
`partial`; итог проверяется после terminal barrier.
|
|
- Сценарий остановки и перезапуска доказан тестами: нет бесконечного ожидания,
|
|
после остановки новые попытки не создаются.
|
|
- Сохранены существующие наборы проверок auth/money/publication, полный
|
|
`backend verify` на финальном изменении зелёный.
|
|
|
|
## Assumptions / Dependencies
|
|
|
|
- Топология остаётся одно-процессной; межпроцессный lease и мультреплики не
|
|
требуются.
|
|
- Истечение ожидания не отменяет уже начатый запрос к T-Bank; защита
|
|
опирается на существующие ограничения CAS и правило срока следующего обхода.
|
|
- Причина прерывания фиксируется существующим диагностическим полём, поэтому
|
|
HTTP contract и публичный словарь состояний не меняются; упомянутое в задаче
|
|
состояние `interrupted` реализуется как частичный успех либо неуспех.
|
|
- Graceful drain добавляется только если тест контролируемой остановки докажет
|
|
такую необходимость.
|
|
- Правило устаревшей публикации относится к итогу попытки и данным её шагов;
|
|
существующие требования `tbank-data-sync` уже запрещают выдавать неполный или
|
|
продолжающийся результат за полный, поэтому их изменение не планируется.
|