Перейти к содержанию

Обработчик обмена

Обработчик обмена — обычная обработка конфигурации или расширения, имя которой указано в реквизите шины «Обработка». Подсистема создаёт её экземпляр в начале каждого сеанса и вызывает методы модуля объекта в предопределённых точках. Всё прикладное содержание обмена живёт здесь.

Все перечисленные ниже методы должны быть объявлены в модуле объекта с ключевым словом Экспорт. Обработчику отправки нужны методы отправки, обработчику приёма — методы приёма; смешивать их в одной обработке допустимо, если по ней работают обе шины.

Реквизиты обработки

Перед вызовом подсистема заполняет реквизиты обработки, если они в ней объявлены:

Реквизит Тип Значение
Шина СправочникСсылка.КафкаШины шина, по которой идёт сеанс
Узел ПланОбменаСсылка узел плана обмена шины

Объявлять их необязательно — обработке без этих реквизитов ничего не передаётся. Если реквизит объявлен, но его тип не позволяет принять значение, сеанс завершится ошибкой инициализации.

Экземпляр обработки не один

В многопоточном сеансе каждый поток — отдельное фоновое задание, и в нём создаётся собственный экземпляр обработки. Состояние, накопленное в переменных модуля на одном пакете, недоступно другому потоку и не переживает границу сеанса. Общие данные храните в базе, а не в модуле обработки.

Методы отправки

ВыгружаемыеОбъектыМетаданных

Функция ВыгружаемыеОбъектыМетаданных() Экспорт

Возвращает таблицу значений с колонками ПолноеИмя, Порядок и РазмерПакета. Определяет, какие таблицы плана обмена отправляются и в какой очерёдности; строки должны быть отсортированы по колонке Порядок. Подробнее — Отправка данных.

ПередВыгрузкойШины

Функция ПередВыгрузкойШины(ШинаИнфо, Заголовки, Адаптер) Экспорт

Вызывается один раз в начале сеанса. Возврат Ложь отменяет сеанс. В Заголовки (соответствие) можно положить заголовки, которые получат все сообщения сеанса. Адаптер позволяет обратиться к Kafka напрямую — например, проверить наличие темы.

ПослеВыгрузкиШины

Процедура ПослеВыгрузкиШины(ШинаИнфо, ИнформацияОбОшибке) Экспорт

Вызывается в конце сеанса, в том числе после ошибки: в этом случае в ИнформацияОбОшибке передаётся описание ошибки, иначе — Неопределено. Подходящее место для прикладного уведомления или отметки о завершении.

ПередВыгрузкойТаблицы

Функция ПередВыгрузкойТаблицы(ОбъектМетаданныхИнфо, Заголовки) Экспорт

Вызывается перед отправкой очередного объекта метаданных, у которого есть зарегистрированные изменения. Возврат Ложь пропускает его. Заголовки — копия заголовков сеанса, дополнения попадут во все сообщения этого объекта метаданных.

ПослеВыгрузкиТаблицы

Процедура ПослеВыгрузкиТаблицы(ОбъектМетаданныхИнфо) Экспорт

Вызывается после того, как все пакеты объекта метаданных розданы потокам.

ПередВыгрузкойПакета, ПослеВыгрузкиПакета

Процедура ПередВыгрузкойПакета(ОбъектМетаданныхИнфо, Адаптер) Экспорт
Процедура ПослеВыгрузкиПакета(ОбъектМетаданныхИнфо) Экспорт

Вызываются в потоке, обрабатывающем пакет, — до и после обхода его объектов. Здесь удобно готовить данные, общие для пакета: кэш, дополнительные запросы, соединение с внешней системой.

ПередВыгрузкойОбъекта

Функция ПередВыгрузкойОбъекта(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт

Вызывается внутри транзакции, после того как объект прочитан и снят с регистрации. Возврат Ложь отменяет отправку сообщения по этому объекту — регистрация при этом уже снята, то есть объект считается обработанным. Заголовки — копия заголовков объекта метаданных, дополнения попадут только в это сообщение.

Объект — прочитанный объект: менеджер значения константы, объект ссылочного типа, набор записей регистра или УдалениеОбъекта, если ссылочный объект уже удалён из базы.

СообщениеКлюч, СообщениеЗначение

Функция СообщениеКлюч(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт
Функция СообщениеЗначение(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт

Формируют ключ и значение сообщения. Допустимые типы возвращаемых значений определяются сердесами шины; Null отправляет сообщение-надгробие, Неопределено считается ошибкой. См. Сериализация ключей и значений.

Готовьте данные один раз

Оба метода вызываются на каждый объект и уже после ПередВыгрузкойОбъекта. Чтобы не собирать одно и то же дважды, ключ и значение обычно формируют в ПередВыгрузкойОбъекта, складывают в переменные модуля, а СообщениеКлюч и СообщениеЗначение только возвращают готовое — как в скелете ниже.

СообщениеСуффиксТемы

Функция СообщениеСуффиксТемы(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт

Вызывается только если имя темы шины заканчивается на *. Возвращённая строка дописывается к префиксу темы. Пустое значение — ошибка.

ПослеВыгрузкиОбъекта

Процедура ПослеВыгрузкиОбъекта(Объект, ОбъектМетаданныхИнфо, RecordMetadata) Экспорт

Вызывается после фиксации транзакции. RecordMetadata — структура с ответом Kafka: topic, partition, offset, timestamp, serializedKeySize, serializedValueSize.

Методы приёма

ПередЗагрузкойРаздела

Функция ПередЗагрузкойРаздела(Тема, Раздел, Адаптер) Экспорт

Вызывается до начала чтения раздела. Возврат Ложь исключает раздел из сеанса.

Процедура загрузки

Процедура <имя из реквизита шины>(Сообщение) Экспорт

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

ПослеЗагрузкиРаздела

Процедура ПослеЗагрузкиРаздела(Тема, Раздел, Позиция) Экспорт

Вызывается по завершении чтения раздела; Позиция — смещение, с которого начнётся следующий сеанс.

Структура ШинаИнфо

Фиксированная структура с настройками шины — тем же составом, что и реквизиты справочника: Ссылка, Наименование, Кластер, Узел, ОбменНаправление, Тема, КлючСердес, ЗначениеСердес, ОбменКоличествоПотоков, ОбменДлительностьСеанса, ПриемПроцедура, ПриемВРеальномВремени, ПриемТаймаутОжидания, КлиентТаймаут, Обработка, параметры расписания и другие.

Дополнительно вычисляются:

Поле Значение
Тема имя темы с учётом контура бэкапа
ТемаЭтоПрефикс Истина, если имя темы заканчивается на *
ТемаПрефикс имя темы без завершающего *

Структура ОбъектМетаданныхИнфо

Фиксированная структура с описанием объекта метаданных, чтобы прикладной код не разбирал полное имя строками:

Поле Значение
ПолноеИмя, Имя, Вид, Представление идентификация объекта метаданных
ЭтоКонстанта, ЭтоСправочник, ЭтоДокумент, ЭтоРегистрСведений, … признаки вида объекта
ЭтоСсылочныйОбъект, ЭтоРегистр, ЭтоНезависимыйРегистр, ЭтоПодчиненныйРегистр обобщённые признаки
КлючевыеПоля фиксированный массив имён ключевых полей: Ссылка, Регистратор или измерения
Тип тип объекта: СправочникОбъект.…, РегистрСведенийНаборЗаписей.… и т. п.

Скелет обработчика отправки

Перем мСообщениеКлюч;
Перем мСообщениеЗначение;

#Область ПрограммныйИнтерфейс

Функция ВыгружаемыеОбъектыМетаданных() Экспорт

    Результат = Новый ТаблицаЗначений;
    Результат.Колонки.Добавить("ПолноеИмя"      , Новый ОписаниеТипов("Строка"));
    Результат.Колонки.Добавить("Порядок"        , Новый ОписаниеТипов("Число"));
    Результат.Колонки.Добавить("РазмерПакета"   , Новый ОписаниеТипов("Число"));

    Для Каждого ЭлементСостава Из Метаданные.ПланыОбмена.<<ИмяПлана>>.Состав Цикл

        МетаданныеПолноеИмя = ЭлементСостава.Метаданные.ПолноеИмя();
        ТаблицаИнфо = КафкаПовтИсп.ОписаниеОбъектаМетаданных(МетаданныеПолноеИмя);

        Порядок = 0;

        Если ТаблицаИнфо.ЭтоКонстанта Тогда
            Порядок = Порядок + 100;
        ИначеЕсли ТаблицаИнфо.ЭтоСправочник Тогда
            Порядок = Порядок + 200;
        ИначеЕсли ТаблицаИнфо.ЭтоДокумент Тогда
            Порядок = Порядок + 300;
        Иначе // регистры
            Порядок = Порядок + 400;
        КонецЕсли;

        Если Ложь Тогда
        Иначе // по умолчанию
            Порядок = Порядок + 50;
        КонецЕсли;

        СтрокаРезультат = Результат.Добавить();
        СтрокаРезультат.ПолноеИмя = ТаблицаИнфо.ПолноеИмя;
        СтрокаРезультат.Порядок = Порядок;
        СтрокаРезультат.РазмерПакета = 200;

    КонецЦикла;

    Результат.Сортировать("Порядок");

    Возврат Результат;

КонецФункции

Функция ПередВыгрузкойШины(ШинаИнфо, Заголовки, Адаптер) Экспорт

    Заголовки.Вставить("source", "1c");

    Возврат Истина;

КонецФункции

Процедура ПослеВыгрузкиШины(ШинаИнфо, ИнформацияОбОшибке) Экспорт
КонецПроцедуры

Функция ПередВыгрузкойТаблицы(ОбъектМетаданныхИнфо, Заголовки) Экспорт

    Заголовки.Вставить("entity", ОбъектМетаданныхИнфо.Имя);

    Возврат Истина;

КонецФункции

Процедура ПослеВыгрузкиТаблицы(ОбъектМетаданныхИнфо) Экспорт
КонецПроцедуры

Процедура ПередВыгрузкойПакета(ОбъектМетаданныхИнфо, Адаптер) Экспорт
КонецПроцедуры

Процедура ПослеВыгрузкиПакета(ОбъектМетаданныхИнфо) Экспорт
КонецПроцедуры

Функция ПередВыгрузкойОбъекта(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт

    мСообщениеКлюч = Строка(Объект.Ссылка.УникальныйИдентификатор());   

    Если ТипЗнч(Объект) = Тип("УдалениеОбъекта") Тогда

        мСообщениеЗначение = Null; // надгробие

    Иначе

        Данные = Новый Структура;
        Данные.Вставить("код", Объект.Код);
        Данные.Вставить("наименование", Объект.Наименование);

        мСообщениеЗначение = Данные;

    КонецЕсли;

    Возврат Истина;

КонецФункции

Функция СообщениеКлюч(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт
    Возврат мСообщениеКлюч;
КонецФункции

Функция СообщениеЗначение(Объект, ОбъектМетаданныхИнфо, Заголовки) Экспорт
    Возврат мСообщениеЗначение;
КонецФункции

Процедура ПослеВыгрузкиОбъекта(Объект, ОбъектМетаданныхИнфо, RecordMetadata) Экспорт
КонецПроцедуры

#КонецОбласти

Пример рассчитан на шину с сердесом ключа «Строка» и сердесом значения «СтруктураJson».