@hlf-explorer/monitor
@hlf-explorer/monitor — это переиспользуемая библиотека, которую встраивают прикладные приложения,
когда им нужно реагировать на то, что происходит в ledger. Здесь есть тонкость, которую лучше
уловить сразу, чтобы потом не путаться: monitor не ходит в Fabric напрямую. Он слушает API самого
эксплорера, а backend эксплорера уже наполнил базу сырыми блоками. Иными словами, backend отвечает
за сырьё, а monitor извлекает из него прикладной смысл.
Движок отслеживания — LedgerMonitor. Он подключается к ledger по сокету, по таймеру сверяет высоту
с сохранённой и на новые блоки ставит задачу разбора. При старте он ещё и добирает пропущенные блоки,
так что ни один блок не выпадет из обработки, даже если приложение какое-то время лежало.
Самое интересное начинается в обработчике разбора — LedgerBlockParseHandler. Он держит реестр
парсеров по именам событий chaincode и в одной транзакции базы проходит по всем событиям блока,
отдавая каждое своему парсеру. А парсер — это LedgerEventParser, и именно его наследует прикладной
код, описывая, что делать с конкретным бизнес-событием. Внутри парсер складывает результат в четыре
корзины, и это деление принципиально:
entities— прикладные сущности, которые сохраняются тут же, внутри той же транзакции.events— доменные события, которые рассылаются сразу после коммита, локально.socketEvents— события, которые уходят клиентам по сокету.commands— действия, которые парсер не может выполнить сам внутри транзакции, и которые отправляются другим сервисам приложения уже после коммита.
На этом разделении стоит задержаться, потому что именно с ним связано честное ограничение, о котором мы пишем прямо. Сущности сохраняются атомарно вместе с самим фактом «блок разобран», а вот команды отправляются после коммита и без ожидания результата. Значит, если процесс упал между коммитом и рассылкой, команда теряется: база помнит, что блок разобран, а действие, которое должно было за ним последовать, не случилось. Для системы учёта это означает расхождение, и закрываем мы это паттерном transactional outbox — подробнее о статусе в roadmap.