Многопоточное выполнение процедуры с помощью ДлительныеОперации
В публикации:
Приведен шаблон для запуска многопоточной операции для различных вариантов размещения многопоточной операции, в том числе в модуле объекта внешней обработки, встроенной в справочник Дополнительные отчеты и обработки;
Представлен вариант корректного отображения прогресса многопоточной операции;
Приведены замеры, демонстрирующие целесообразность использования нового механизма для увеличения производительности.
- Описание
- Подробнее
Описание
Введение
Недавно столкнулся с необходимостью увеличить скорость работы одной внешней обработки. Оказалось, что начиная с версии БСП 3.1.6 появился новый функционал.
Новые возможности для разработчиков в версии 3.1.6
Базовая функциональность
- Для ускорения выполнения длительных операций предусмотрена возможность выполнить обработчик длительной операции в несколько потоков. Для этого необходимо:
- Разделить данные на наборы, где каждый элемент набора будет обработан в отдельном фоновом задании.
- Из программного интерфейса общего модуля
ДлительныеОперации
для запуска процедуры длительной операции вызвать функциюВыполнитьПроцедуруВНесколькоПотоков
(илиВыполнитьФункциюВНесколькоПотоков
), передав третьим параметром сформированный набор данных. Подробное описание параметров см. в комментарии к этим функциям.- Максимально допустимое количество одновременно работающих фоновых заданий может быть задано администратором в разделе Администрирование — Общие настройки — Производительность
- В файловой информационной базе и при работе в модели сервиса длительные операции всегда выполняются в один поток.
- Пример см. в демонстрационной конфигурации в форме
ЗагрузкаАдресногоКлассификатора
регистра сведенийАдресныеОбъекты.
В описании функции ВыполнитьПроцедуруВНесколькоПотоков (или ВыполнитьФункциюВНесколькоПотоков, но для удобства не буду разделять) описано, что код который будет выполняться в фоне должен быть в:
- В общем модуле ("МойОбщийМодуль.МояПроцедура")
- Модуле менеджера объекта ("Отчет.ЗагруженныеДанные.Сформировать")
- Модуле обработки ("Обработка.ЗагрузкаДанных.МодульОбъекта.Загрузить")
Но мне нужно было запустить процедуру модуля объекта внешней обработки, встроенной в справочник Дополнительные отчеты и обработки. В данном контексте я вспомнил про процедуру ВыполнитьПроцедуруМодуляОбъектаОбработки, что натолкнуло на мысль о том, что есть явно неописанная возможность многопоточно запустить код находящийся в модуле объекта дополнительной обработки, если в качестве первого параметра в функцию ВыполнитьПроцедуруВНесколькоПотоков передать Выполнить ПроцедуруМодуляОбъектаОбработки. Однако при первой попытке реализовать данный вариант я столкнулся с непониманием к ак правильно передать параметры, примеров такого использования функции не нашел, поэтому появилась идея разобраться и опубликовать результаты.
Цели
Перед тем как приступать к реализации, поставим цели, которых хотим достичь в рамках публикации.
- Публикация должна ответить читателю на ряд вопросов:
- Как многопоточно запустить процедуру расположенную в серверном общем модуле?
- Как с помощью ДлительныеОперации запустить процедуру модуля объекта внешней обработки?
- Как многопоточно запустить процедуру модуля объекта внешней обработки?
- Как отобразить прогресс многопоточной операции?
- В публикации должны быть продемонстрированы замеры производительности в зависимости от кол-ва потоков, наглядно показан выигрыш в производительности
Цели поставлены, приступим к реализации.
Реализация
Разработка проводилось на демонстрационной базе БСП версии 3.7.1.327.
Начнем с краткого описания того, что будет делать наша обработка:
- Получаем выборку ссылок на N-ое кол-во документов _ДемоПоступлениеТоваров
- Разбиваем ее на порции размером N/k, где k — кол-во потоков
- Формируем структуры параметров для функции ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков
- Запускаем длительную операцию которая поменяет в каждом обрабатываемом документе значение реквизита Комментарий
Форма обработки
Модуль объекта
Процедура ниже будет запускаться многопоточно