В практике разработки на платформе 1С:Предприятие 8.3 нередко возникает задача внепланового запуска внешней обработки, подключенной в справочнике Дополнительные отчеты и обработки. Типичный сценарий — необходимость выполнить тяжелую обработку или обмен данными не по стандартному расписанию, а по определенному внешнему событию, например, при получении входящего HTTP-запроса в HTTP-сервисе.
Если вызвать метод выполнения обработки напрямую в модуле HTTP-сервиса, веб-клиент или интеграционная система будут вынуждены ожидать завершения всей процедуры, что приводит к превышению таймаутов соединения (Time-out) и блокировке потоков веб-сервера. Разберем, почему нельзя напрямую «стартануть» регламентное задание и как правильно организовать асинхронное фоновое выполнение.
Проанализируем ключевое архитектурное ограничение платформы 1С. Объект метаданных РегламентныеЗадания предназначен для настройки расписания и хранения параметров автоматического запуска. Самостоятельно инициировать немедленное выполнение через метод регламентного задания платформа не позволяет. Непосредственным исполнителем программного кода на сервере 1С выступает объект ФоновыеЗадания.
Когда регламентное задание срабатывает по таймеру, кластер серверов 1С автоматически создает под него фоновое задание. Следовательно, для ручного или программного внепланового старта необходимо напрямую использовать менеджер фоновых заданий — метод ФоновыеЗадания.Выполнить().
Перед реализацией кода рассмотрим обязательные технические требования платформы к запуску фоновых заданий:
ФоновыеЗадания.Выполнить() принимает имя процедуры в виде строки "ИмяОбщегоМодуля.ИмяПроцедуры". Процедура обязательно должна быть экспортной и находиться исключительно в неглобальном общем модуле с установленным флажком Сервер. Нельзя передавать методы из модулей форм, объектов, менеджеров или модулей HTTP-сервисов.Разберем по шагам, как выстроить цепочку вызова из HTTP-сервиса или другого серверного обработчика события.
Шаг 1. Создание процедуры-обертки в серверном общем модуле
Создадим или откроем существующий неглобальный общий модуль (например, ИнтеграцияСервер) с включенным свойством Сервер (и снятым свойством Внешнее соединение, если оно не требуется). Разместим в нем экспортную процедуру, которая будет находить дополнительную обработку и запускать ее команду средствами Библиотеки Стандартных Подсистем (БСП):
Процедура ЗапуститьКомандуВнешнейОбработки(СсылкаНаОбработку, ИмяКоманды) Экспорт
// Выполняем регламентную команду дополнительной обработки штатными средствами БСП
ДополнительныеОтчетыИОбработки.ВыполнитьОбработкуПоРегламентномуЗаданию(
СсылкаНаОбработку,
ИмяКоманды
);
КонецПроцедуры
Шаг 2. Асинхронный запуск фонового задания из HTTP-сервиса
Посмотрим на пример кода в методе-обработчике входящего запроса HTTP-сервиса. Здесь мы подготавливаем параметры, формируем фоновое задание и сразу возвращаем вызывающей стороне успешный HTTP-ответ (код 200 или 202 Accepted), не дожидаясь завершения фонового процесса:
Функция ОбработатьЗапрос(ЗапросHTTP)
// 1. Находим ссылку на дополнительную обработку в справочнике
СсылкаОбработка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("ИнтеграцияССервисом");
Если Не ЗначениеЗаполнено(СсылкаОбработка) Тогда
Ответ = Новый HTTPСервисОтвет(404);
Ответ.УстановитьТелоИзСтроки("Обработка не найдена в системе", "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
КонецЕсли;
// 2. Формируем массив параметров для передачи в фоновое задание
ИмяКоманды = "ВыгрузитьДанные";
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(СсылкаОбработка);
ПараметрыЗадания.Добавить(ИмяКоманды);
// 3. Задаем уникальный ключ, чтобы исключить параллельный запуск дублей
КлючЗадания = "ВыгрузкаДанных_" + Строка(СсылкаОбработка.УникальныйИдентификатор());
НаименованиеЗадания = "Асинхронный запуск обработки: " + СсылкаОбработка.Наименование;
// 4. Запускаем фоновое задание
ФоновыеЗадания.Выполнить(
"ИнтеграцияСервер.ЗапуститьКомандуВнешнейОбработки",
ПараметрыЗадания,
КлючЗадания,
НаименованиеЗадания
);
// 5. Мгновенно возвращаем клиенту подтверждение о приеме задания
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки("Задание успешно поставлено в очередь выполнения", "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
КонецФункции
Если конфигурация разработана на основе БСП, вместо прямого обращения к объекту ФоновыеЗадания рекомендуется использовать общий модуль ДлительныеОперации. Рассмотрим преимущества этого подхода: БСП берет на себя управление ключами сеансов, регистрацию прогресса выполнения и работу с временным хранилищем.
Пример инициализации длительной операции на стороне сервера:
ПараметрыПроцедуры = Новый Структура;
ПараметрыПроцедуры.Вставить("СсылкаНаОбработку", СсылкаОбработка);
ПараметрыПроцедуры.Вставить("ИмяКоманды", "ВыгрузитьДанные");
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне();
ПараметрыВыполнения.НаименованиеФоновогоЗадания = "Выгрузка данных по запросу";
ПараметрыВыполнения.КлючФоновогоЗадания = "ВыгрузкаДанных";
// Запуск длительной операции
РезультатЗапуска = ДлительныеОперации.ЗапуститьВыполнениеВФоне(
"ИнтеграцияСервер.ВыполнитьДействиеДлительнойОперации",
ПараметрыПроцедуры,
ПараметрыВыполнения
);
При интеграции фоновых запусков важно учесть два нюанса:
Ключ: Передача строкового ключа в метод ФоновыеЗадания.Выполнить предотвращает параллельный запуск одинаковых процессов. Если фоновое задание с таким ключом уже активно, платформа не позволит повторно запустить процедуру с тем же ключом до завершения текущей.БезопасныйРежим = Истина), что ограничивает доступ к файловой системе сервера, вызовам внешних компонент и COM-объектов. Если логика обработки требует данных операций, в справочнике Дополнительные отчеты и обработки для нее должны быть предварительно настроены соответствующие разрешения безопасности.