При изучении и доработке конфигураций на базе Библиотеки стандартных подсистем (БСП) разработчики нередко сталкиваются с кодом регистрации различных модулей в коллекциях КлиентскиеОбработчики и СерверныеОбработчики. На первый взгляд такой синтаксис вызывает вопросы: откуда берутся эти переменные, где они инициализируются и как платформа 1С их обрабатывает. Разберем детально архитектуру этого механизма, выясним причину его появления и научимся правильно объявлять свои обработчики.
В платформе 1С:Предприятие штатный механизм подписок на события жестко привязан к объектам метаданных — справочникам, документам, планам обмена или процессам записи. Однако для создания модульной архитектуры конфигурации часто требуется шина абстрактных программных событий. Например, подсистема обновления метаданных или подсистема вариантов отчетов должна уведомить другие независимые подсистемы о наступлении определенного этапа работы.
Чтобы избежать жестких циклических связей между модулями и обеспечить возможность выборочного внедрения подсистем БСП, разработчики библиотеки реализовали собственную событийную модель:
"ИмяПодсистемы\ИмяСобытия".Посмотрим на пример кода, с которого начинается подключение обработчиков внутри служебного модуля подсистемы:
СерверныеОбработчики["СтандартныеПодсистемы.БазоваяФункциональность\ПриДобавленииПереименованийОбъектовМетаданных"].Добавить(
"АнализЖурналаРегистрацииСлужебный");
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
СерверныеОбработчики["СтандартныеПодсистемы.ВариантыОтчетов\ПриНастройкеВариантовОтчетов"].Добавить(
"АнализЖурналаРегистрацииСлужебный");
КонецЕсли;
Параметр СерверныеОбработчики представляет собой универсальную коллекцию — Соответствие. Ключом данного соответствия выступает строка пути к событию, а значением — Массив строк с именами общих модулей, которые вызываются при наступлении события.
Проанализируем, где именно рождается эта коллекция. Инициализация выполняется ядром БСП в общем модуле СтандартныеПодсистемыСервер внутри экспортной функции ОбработчикиСобытий:
// Фрагмент механизма сбора обработчиков в СтандартныеПодсистемыСервер
Если Описание.ДобавлятьОбработчикиСлужебныхСобытий Тогда
Модуль.ПриДобавленииОбработчиковСлужебныхСобытий(
ОбработчикиКлиентскихСлужебныхСобытийПоПодсистемам[Подсистема],
ОбработчикиСерверныхСлужебныхСобытийПоПодсистемам[Подсистема]
);
КонецЕсли;
Таким образом, коллекция передается во входной параметр экспортной процедуры ПриДобавленииОбработчиковСлужебныхСобытий(КлиентскиеОбработчики, СерверныеОбработчики) каждого служебного модуля подсистем конфигурации.
Разберем по шагам, как БСП оптимизирует вызовы и почему постоянный опрос модулей не замедляет работу всей системы:
ПараметрыСлужебныхСобытий (хранилище значений).СтандартныеПодсистемыПовтИсп). Это исключает повторные обращения к базе данных при многократных вызовах событий.Рассмотрим распространенные проблемы, возникающие при внедрении собственных событий или изменении стандартных модулей БСП:
ПриДобавленииОбработчиковСлужебныхСобытий или зарегистрировали новый модуль, но программа выдает ошибку о том, что параметр служебных событий не заполнен или событие не найдено. Причина заключается в том, что константа ПараметрыСлужебныхСобытий хранит старую структуру.Выясним, какие действия необходимо предпринять для корректной работы служебных обработчиков:
/C ЗапуститьОбновлениеИнформационнойБазы либо вызовите в коде ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы(). Это инициирует перезапись константы служебных событий.
Если ОбщегоНазначения.ПодсистемаСуществует("ИмяПодсистемы") Тогда
СерверныеОбработчики["ИмяПодсистемы\ИмяСобытия"].Добавить("МойСлужебныйМодуль");
КонецЕсли;
ПараметрыСлужебныхСобытий в пользу переопределяемых модулей (например, ОбщегоНазначенияПереопределяемый) и механизма расширений, что упрощает поиск ссылок и статическую проверку конфигурации.