/one-c-events-rs

Генератор событий для 1С:Предприятие (кода нет, только идея)

one-c-events-rs

Генератор событий для 1С:Предприятие (кода нет, пока только идея)

Введение

В 1С часто используется техника опросов, например для:

  • обменов, данные изменяются, регламентное задание периодически получает изменения и отправляет эти данные.
  • при программном запуске фонового задания, часто приходится периодически опрашивать сервер, чтобы узнать, завершилось оно или нет. В технологии 1С:Фреш в подсистеме Очередь заданий ФЗ запускаются из неразделенного сеанса путем входа в нужную область, чтобы проверить что ФЗ завершилось нужно опять входить в эту область, это очень накладно, приходится использовать разные хаки.
  • в Очереди заданий когда добавляется новое задание, нужно как-то среагировать и возможно запустить его, тут тоже используется регламентное задание, которое периодически считывает такие задания и дальше управляет ими.

Эти опросы выполняются с некоторой задержкой, например регламентные задания не принято запускать чаще чем 1 раз в 60 сек, соответственно опертивность реагирования слишком низкая. В технологии 1С:Фреш в одной базе могут находиться сотни и тысячи приложений, соответственно это такое же количество регламентных заданий. Даже если в этих приложениях никто не работает, каждые 60 секунд вынуждены запускать эти сотни или тысячи сеансов, это излишняя нагрузка на серверы.

Исходя из предыдущего описания проблемы, хотелось бы иметь реактивный подход, когда прикладной код уведомляется о происходящих событиях.

Когда данные изменяются, то эти данные можно прочитать из другого сеанса только после завершения транзакции, соответственно первое полезное событие - после транзакции. И второе событие - это завершение ФЗ.

Возможные события

После транзакции

Возможные варианты:

  1. Парсить Журнал регистрации(ЖР) на лету и генерировать нужные события. ЖР содержит события по добавлению/изменению с именами метаданных, а также содержит идентификаторы транзакций и события завершения транзакции.
  2. Ловить события из СУБД, например в postgresql есть https://www.postgresql.org/docs/current/sql-notify.html, нужно создать триггеры для нужных таблиц и в них генерировать события, нативные клиенты могут получать уведомления от postgres и дальше уже можно будет уведомить 1С. Но такой вариант скорее всего будет нарушать лицензионное соглашение 1С (но я не знаю, является ли нарушением создание триггера).

Завершение сеансов

Возможные варианты:

  1. Аналогично парсить ЖР.
  2. Получать сведения из кластера, например из ras, но там тоже нет событий, придется использовать технику опросов.

Механизм уведомлений

Возможные варианты:

  1. Отдельно запущенное приложение будет ожидать событий и когда они появятся, будет вызывать http-сервис на стороне 1С.
  2. Постоянно запущенное ФЗ будет слушать события с помощью внешней компоненты.
  3. Постоянно запущенное ФЗ будет получать события с помощью HttpСоединение и чтобы не выполнять частые запросы, будет использоваться long polling.

Выбранное решение

Оба вида событий можно получать из ЖР, поэтому кажется логичным использовать именно его. Также можно из ЖР извлечь другие полезные события, например запись пользователя ИБ или появление другой записи, например программно сформированной. Вместо ЖР можно было бы использовать Технологический журнал(ТЖ), но непонятно, какие у него плюсы в данном случае.

В общем случае прикладной код и запись журнала регистрации может выполняться на разных хостах, то универсальнее будет использовать отдельное приложение, а не внешнюю компоненту.

Вызов http-сервиса 1С имеет накладные расходы (на запуск и на восстановление состояния, повторное использование сеансов только частично решает эти проблемы), то выгодее иметь постоянно запущенное ФЗ, которое в цикле будет опрашивать (long polling) HTTP endpoint этого приложения.

Приложение планируется писать на Rust, т.к. хочется, чтобы данное приложение потребляло минимум ресурсов (и память и процессор). Rust для этого все имеет, например встроенные строки в формате UTF-8 и возможность парсинга без аллокаций. Ожидается, что нагрузка на диск создаваться не будет, т.к. ОС так устроена, что при записи в файл, эти данные остаются в памяти, пока их не вытеснят другие данные. Поэтому, при чтении только что записанных данных, они будут отданы из памяти, а не с диска. На современном процессоре, парсер реализованный на rust, парсит примерно 2Гб в секунду на одном ядре, это просто огромная скорость, в реальности даже на загруженных базах, ЖР регистрации будет в 1000 раз меньше.