# Signal Bus
В ходе работы системы часто возникают различные события, напрмер:
* Добавление объекта
* Создание линка
* Возникновение аварии
* Создание TT
* etc.
На настоящий момент они логгируются в разные журналы, и, в отдельных случаях, формируются сообщения в очереди или назначаются job'ы.
Для повышения эксплуатационных свойств и упрощения внутренней архитектуры предлагается ввести единую внутреннюю шину событий и четко разделить зоны отвесвенности генераторов и обработчиков событий.
## Таблица signals
Создается в ClickHouse и имеет поля:
* date - дата, параметр для партиционирования
* timestamp - отметка времени
* code - Код события (см. далее)
* ref - строка id связанного объекта, модель зависит от кода события
* creator - код создателя события (сервис)
* user - Опциональный username, если событие возникло в результате начального воздействия пользователя
* span - id span'а
* parent_span - родительский span
* msg - Текстовое сообщениие (строка лога)
* data - JSON события, зависит от типа.
* labels - список меток
Используется engine Kafka с чтением из topic `signals`
## Отправка сигнала
Осуществляется путем публикации в topic'е `signals` в Redpanda.
Для сохранения последовательности событий в качестве ключа шардирования по партициям выступает ref. Таким образом, для одной сущности порядок записи в базу остается консистентным.
Все публикации в топик signals автоматически попадают в таблицу signals.
## Python API для отправки сигналов
``` py
async def signal(
code:str,
ref: Optional[str]=None,
creator: Optional[str]=None,
msg: Optional[str]=None,
data: Optional[Dict[str, Any]]=None,
labels: Optional[str]=None,
) -> None: ...
def signal_sync(....) -> None: ...
```
При этом span достается автоматически из контекста.
Пользователь также должен доставаться из пользовательского контекска (реализовать в middleware)?
## Коды сигналов
Коды иерархичны для удобства фильтрации.
| Код | ref | Описание |
| --- | --- | --- |
| user::logged | user id | Пользователь залогинился в систему |
| mo::created | mo id | Managed Object создан |
| mo::changed | mo id | Аттрибуты MO изменены |
| mo::deleted | mo id | MO удален |
| mo::state | mo id | Изменен state MO |
| mo::interface::created | mo id | Добавлен интерфейс |
| mo::interface::changed | mo id | Аттрибуты интерфейса изменены |
| mo::interface::deleted | mo id | Интерфейс удален |
| mo::linked | mo id | Установлен линк (посылается для всех связанных MO) |
| mo::unlinked | mo id | Линк удален (посылается для всех связанных MO)|
| mo::config | mo id | Изменен конфиг |
| job::scheduled | task id | Запланирован job |
| job::removed | task id | Распиисаниие job удалено |
| job::started | task id | Запущен job |
| job::completed | task id | Job завершен успешно |
| job::failed | task id | Job завершился неудачно |
| alarm::raised | mo id | Создание аварии |
| alarm::cleared | mo id | Очистка аварии |
| tt::open | mo id | Создание TT |
| tt::close | mo id | Закрытие TT |
| service::started |
| service::stopped |
| system::deploy |
## Изменения моделей
Отслеживаются декоратором `@change`. Возможно использование волшебных методов для форматирования итогового json.
## Переток меток
Вводятся дополнительные правила:
* `expose_signal`
## Подписка
!!! Необходимо тестирование
Возможны варианты:
* Пересылка сообщений в служебные topic
* Live view на таблицу signals с подпиской WATCH
## Перерабатываемые механизмы
### Scheduler
Перерабатываеся с разделением на сам scheduler, который посылает сигналы в нужное время и работает с расписаниями, и на worker'ы, которые обрабатывают задачи
### Discovery
На первом шаге происходит разделение опроса и обработки его результатов. На втором - сервис ликвидируется и инициация опроса переносится на активаторы и worker'ы.
### DataStream
Перерасчет затронутых datastream переносится на worker'ы (с механизмом задержки задания)
Сервисы datastream перестают отслеживать коллекцию в mongo и становятся подписчиками на сигналы.
Note: С данного момента использование Replica Set становится необязательным.
### Escalation
Переводится на worker и реализуется через отложенные задачи
### Alarm Trigger
Подписка на события
## Дополнительные механизмы
Часть handler'ов должна деплоиться на worker'ах после их запуска, чтобы иметь возможность подписаться на события. Необходимо продумать механизм.