Docs security / security (push) Successful in 8s
Docs verify / verify (push) Successful in 13s
Conventional commits / commits (pull_request) Successful in 12s
Docs security / security (pull_request) Successful in 8s
Docs verify / verify (pull_request) Successful in 14s
147 lines
14 KiB
Markdown
147 lines
14 KiB
Markdown
# 017. Локальное чтение данных T-Bank и фоновая синхронизация
|
|
|
|
**Status:** Accepted — историческое архитектурное направление. Решения ниже о
|
|
request-driven запуске, ручном обновлении и отсутствии периодического обхода
|
|
заменены [ADR 019](019-hourly-reads-and-online-instrument-reference.md).
|
|
|
|
Prefetch policy ниже заменена [ADR 018](018-minimal-runtime-coordination.md):
|
|
свечи загружаются по запрошенному диапазону, без предварительной загрузки
|
|
всей истории бумаг портфеля. Остальные гарантии локального хранения сохранены.
|
|
|
|
Реализация `persist-tbank-data` добавлена в рабочие ветки приложения;
|
|
performance/browser и canonical application gates пройдены. Это не отметка
|
|
развёртывания в production. Ниже сохранён контекст
|
|
принятия решения, а текущее устройство описывает
|
|
[модель свежести](../architecture/cross-cutting/data-freshness.md).
|
|
|
|
## Context
|
|
|
|
Инвестиционная история не сохраняется в БД. Серверные кэши находятся в памяти
|
|
процесса, а загрузка операций, аналитики дохода и рыночной истории зависит
|
|
от повторных обращений к T-Bank. Для журнала операций запрос доступных счетов
|
|
выполняется даже перед чтением кэшированной страницы. Сохранение только
|
|
ответов без изменения этого пути не устранит ожидание внешнего API.
|
|
|
|
Нужно ускорить все экраны, использующие T-Bank, и уменьшить повторную загрузку
|
|
данных. Текущие механизмы описаны в [политике свежести](../architecture/cross-cutting/data-freshness.md)
|
|
и [журнале операций](../domains/operations/overview.md).
|
|
|
|
## Decision
|
|
|
|
Для уже загруженных данных обычный запрос frontend обслуживается из постоянного
|
|
локального хранилища без ожидания ответа T-Bank. Обновление выполняется в фоне.
|
|
Пользователь видит время последнего успешного обновления и может запросить
|
|
обновление вручную. Сохранённый портфель может ещё не содержать новую сделку;
|
|
эта задержка принята ради быстрого открытия экрана.
|
|
|
|
Синхронизация запускается только запросами пользовательских экранов и ручным
|
|
действием «Обновить». Периодических запусков, ежедневного обновления неактивных
|
|
пользователей и плановой сверки истории нет. Фоновое выполнение означает,
|
|
что уже запрошенная работа не задерживает выдачу сохранённых данных;
|
|
самостоятельное расписание обновлений оно не подразумевает.
|
|
|
|
Обычный запрос запускает обновление, только если нужных данных нет либо
|
|
истёк согласованный срок их свежести:
|
|
|
|
| Данные | Срок свежести |
|
|
| --- | --- |
|
|
| Портфель и текущие цены | 1 минута |
|
|
| Операции текущего месяца | 5 минут |
|
|
| Список доступных счетов | 5 минут |
|
|
| Справочник инструментов и календари купонов и дивидендов | 1 сутки |
|
|
| Незавершённая дневная свеча | 1 минута |
|
|
|
|
Эти сроки проверяются при запросе и не задают расписание фоновых запусков.
|
|
Аналитика дохода зависит от полноты и свежести исходных операций.
|
|
|
|
Полностью загруженные предыдущие месяцы операций повторно читаются из T-Bank
|
|
только по кнопке «Обновить» для показанного периода. Обычный запрос догружает
|
|
отсутствующие интервалы и при необходимости обновляет текущий месяц.
|
|
Завершённые дневные свечи сохраняются; ручное обновление перечитывает
|
|
показанный диапазон. Автоматическое обнаружение поздних операций и исправлений
|
|
в уже полностью загруженных прошлых месяцах не обещается.
|
|
|
|
Кнопка «Обновить» обходит проверку давности и обновляет данные текущего
|
|
экрана: выбранного счёта, доступных счетов в режиме «Все счета» либо
|
|
инструмента и показанной личной истории на его странице. Нажатие не означает
|
|
повторную загрузку всей накопленной истории всех счетов и инструментов.
|
|
|
|
Решение охватывает все экраны с данными T-Bank. Исполненные операции и рыночная
|
|
история сохраняются; текущие позиции, остатки и цены представлены последним
|
|
успешно полученным состоянием. Будущие выплаты остаются изменяемым прогнозом,
|
|
а не исполненными операциями. Это не решение о накоплении исторических снимков
|
|
стоимости портфеля.
|
|
|
|
Рыночная история бумаг текущего портфеля загружается заранее в рамках
|
|
запрошенной пользователем работы. Для остальных бумаг первая загрузка
|
|
начинается при открытии инструмента, результат сохраняется для последующего
|
|
чтения. Предварительная загрузка истории всего каталога не требуется.
|
|
|
|
При первом подключении текущий портфель и недавние операции могут отображаться
|
|
до завершения загрузки более ранней истории. Частично загруженный период явно
|
|
отличается от полного: неполные итоги нельзя выдавать за окончательные,
|
|
а отсутствие загруженных записей — за подтверждённое отсутствие операций.
|
|
Смысл полноты определён в [глоссарии](../glossary.md#полнота-истории-счёта).
|
|
|
|
Первый запрос задаёт приоритет: сначала период, нужный экрану, включая
|
|
периоды сравнения дохода, затем вся доступная история счёта. Уже запущенная
|
|
догрузка может завершиться после ухода пользователя со страницы; нового
|
|
периодического запуска это не создаёт.
|
|
|
|
Полнота относится к успешно загруженным временным интервалам. Смена месяца
|
|
сама по себе не делает завершённым последний неполный интервал прошлого
|
|
месяца: его оставшаяся часть должна быть догружена. Ошибка промежуточной
|
|
страницы не подтверждает полноту и не удаляет ранее сохранённые данные.
|
|
Незавершённая свеча также не становится завершённой только из-за смены дня:
|
|
её окончательное состояние должен подтвердить источник.
|
|
|
|
Целевой ориентир — до 500 мс для обычного серверного запроса к заполненной БД.
|
|
Это согласованная цель измерения, а не подтверждённая характеристика системы.
|
|
Объём данных и набор запросов для проверки предстоит определить.
|
|
|
|
Для этого изменения принято допущение: ID брокерской операции не меняется
|
|
со временем. Обнаружение сменившихся ID и регулярная сверка старой истории
|
|
не входят в объём работы. Это допущение проекта, а не гарантия T-Bank:
|
|
используемый protobuf-контракт допускает изменение ID. Допущение относится
|
|
к идентичности операции; оно не требует игнорировать новые значения полей,
|
|
если операция с прежним ID снова получена от брокера.
|
|
|
|
Подключение T-Bank считается постоянным в рассматриваемом сценарии.
|
|
Архив без подключения, специальная политика хранения после отключения
|
|
и работа с закрытыми счетами пока не проектируются. Это ограничение объёма
|
|
не отменяет существующие проверки доступа и обработку ошибок интеграции.
|
|
|
|
## Alternatives
|
|
|
|
Ожидание свежего ответа T-Bank при каждом открытии экрана сохраняет зависимость
|
|
скорости и доступности интерфейса от брокера. Увеличение времени жизни кэша
|
|
в памяти уменьшает часть повторных запросов, но не сохраняет историю после
|
|
перезапуска и не обеспечивает локальное чтение всех нужных данных.
|
|
|
|
## Consequences
|
|
|
|
Интерфейсу нужны различимые состояния первичной загрузки, полноты истории,
|
|
свежести и ошибки фонового обновления. Успешная загрузка недавних операций
|
|
не подтверждает полноту более ранних периодов или периодов сравнения дохода.
|
|
|
|
Проверки локальной сессии и принадлежности личных данных сохраняются.
|
|
Способ подтверждения брокерского доступа должен позволять обслужить уже
|
|
загруженные данные без синхронного ожидания T-Bank.
|
|
|
|
Повторные запросы одного набора данных должны использовать уже выполняющуюся
|
|
загрузку. Завершённые интервалы и прогресс сохраняются в БД; после перезапуска
|
|
незавершённый интервал повторяется при следующем запросе или ручном обновлении.
|
|
Курсор брокера и максимальная дата полученной операции не доказывают полноту.
|
|
|
|
Ручное обновление периода согласует состав операций и их поля с полностью
|
|
полученным ответом источника. Только успешная загрузка всех страниц позволяет
|
|
зафиксировать полное покрытие, успешное обновление и удалить отсутствующие
|
|
в этом ответе записи периода. Ошибка не превращает частичный ответ в полный.
|
|
|
|
Личные операции и позиции сохраняют принадлежность пользователю и счёту.
|
|
Общие данные инструмента не должны содержать персональные позиции и расчёты;
|
|
поздний результат прежнего подключения не публикуется для нового подключения.
|
|
|
|
Существующие HTTP-контракты пока не поддерживают все необходимые состояния
|
|
загрузки и полноты; их изменение входит в будущую реализацию.
|