1С: Предприятие 8.3.13 . Документация
Руководство разработчика
Глава 18. Механизм заданий
Механизм заданий предназначен для выполнения какой-либо прикладной функциональности по расписанию или асинхронно.
Механизм заданий решает следующие задачи:
- возможность определения регламентных процедур на этапе конфигурирования системы;
- выполнение заданных действий по расписанию;
- выполнение вызова заданной процедуры или функции асинхронно, т. е. без ожидания ее завершения;
- отслеживание хода выполнения определенного задания и получение его статуса завершения (значения, указывающего успешность или неуспешность его выполнения);
- получение списка текущих заданий;
- возможность ожидания завершения одного или нескольких заданий;
- управление заданиями (возможность отмены, блокировка выполнения и др.).
Механизм заданий состоит из следующих компонентов:
- метаданных регламентных заданий,
- регламентных заданий,
- фоновых заданий,
- планировщика заданий.
Регламентные задания предназначены для выполнения прикладных задач по расписанию. Регламентные задания хранятся в информационной базе и создаются на основе метаданных, определяемых в конфигурации. Метаданные регламентного задания содержат такую информацию, как наименование, метод, использование и т. д.
Регламентное задание имеет расписание, которое определяет, в какие моменты времени нужно выполнять связанный с регламентным заданием метод. Расписание, как правило, задается в информационной базе, но может быть задано и на этапе конфигурирования (например, для предопределенных регламентных заданий).
Фоновые задания предназначены для выполнения прикладных задач асинхронно, реализуются средствами встроенного языка.
Планировщик заданий используется для планирования выполнения регламентных заданий. Для каждого регламентного задания планировщик периодически проверяет, соответствует ли текущая дата и время расписанию регламентного задания. Если соответствует, планировщик назначает такое задание на выполнение. Для этого по данному регламентному заданию планировщик создает фоновое задание, которое и выполняет реальную обработку.
18.2. Фоновые задания
18.2.1. Общая информация
Фоновые задания удобно использовать для выполнения сложных вычислений, когда результат вычисления может быть получен через продолжительное время. Механизм заданий имеет средства для выполнения таких вычислений асинхронно.
С фоновым заданием связан метод, который вызывается при выполнении фонового задания. В качестве метода фонового задания может выступать любая процедура или функция не глобального общего модуля, которую можно вызвать на сервере. Параметрами фонового задания могут быть любые значения, которые разрешено передавать на сервер. Параметры фонового задания должны в точности соответствовать параметрам той процедуры или функции, которую оно вызывает. Параметры фонового задания, в сериализованном виде, не могут превышать размер в 1 Гбайт. Если размер сериализованных параметров фонового задания превышает значение 1 Гбайт ‑ формируется исключение. Если методом фонового задания является функция, то ее возвращаемое значение игнорируется.
Фоновое задание может иметь ключ ‑ любое прикладное значение. Ключ вводит ограничение на запуск фоновых заданий ‑ в единицу времени может выполняться только одно фоновое задание с определенным значением ключа и заданным именем метода фонового задания (имя метода состоит из имени модуля и имени процедуры или функции). Ключ позволяет группировать фоновые задания, имеющие одинаковые методы, по определенному прикладному признаку с тем, чтобы в рамках одной группы выполнялось не более одного фонового задания.
Создание и управление фоновыми заданиями выполняются программно из любого соединения. Создавать фоновое задание разрешено любому пользователю. При этом оно выполняется от имени того пользователя, который его создал. Получать задания, а также ожидать их завершения разрешено из любого соединения пользователю с административными правами либо пользователю, который создал эти фоновые задания.
Фоновое задание является чисто сеансовым объектом, но не принадлежит какому-либо пользовательскому сеансу. Для каждого задания создается специальный системный сеанс, выполняющийся от имени того пользователя, который выполнил вызов. Фоновые задания не имеют сохраняемого состояния.
Фоновое задание может порождать другие фоновые задания. В клиент-серверном варианте это позволяет распараллеливать сложные вычисления по рабочим процессам кластера, что может значительно ускорить процесс вычисления в целом. Распараллеливание реализуется порождением нескольких дочерних фоновых заданий с ожиданием завершения каждого из них в основном фоновом задании.
Фоновое задание имеет возможность помещать данные во временное хранилище вызывающего сеанса (см. здесь). Это может быть использовано, например, для передачи в вызывающий сеанс сформированного отчета или подготовленных для обработки данных. Передача данных из вызывающего сеанса в сеанс фонового задания невозможна.
Запуск фонового задания выполняется следующим образом:
- Выполняются служебные действия:
- Фиксируется факт запуска фонового задания в журнале регистрации;
- Устанавливаются параметры соединения с внешними источниками данных ;
- Устанавливается режим интерфейса и т. д.
- В модуле сеанса выполняется обработчик события УстановкаПараметровСеанса ;
- Выполняется собственно фоновое задание.
Завершившиеся успешно или аварийно фоновые задания хранятся в течение суток, а потом удаляются. История выполнения фоновых и регламентных заданий имеет следующие особенности:
● История хранится для каждой информационной базы;
● Хранится история выполнения:
● Фоновых заданий ‑ не более 1 000 заданий.
● Регламентных заданий ‑ не более 1 000 заданий. При этом система пытается хранить не менее 3 последних запусков для каждого различного регламентного задания. При превышении общего ограничения в 1 000 запусков, система будет пытаться обеспечить хранение 2 последних запусков для каждого регламентного задания, а потом 1.
● Системных фоновых заданий ‑ не более 1 000 запусков. В данном разделе речь идет о фоновых заданиях, которые инициируются системой для выполнения каких-либо действий (выполнение отчетов, поиск и т. д.).
18.2.2. Работа с фоновыми заданиями из встроенного языка
ПРИМЕЧАНИЕ. Примеры, приведенные в данном разделе, не являются законченными. Они предназначены только для демонстрации способов работы с фоновыми заданиями.
Управление фоновыми заданиями выполняется с помощью менеджера фоновых заданий (ФоновыеЗадания). С помощью менеджера фоновых заданий предоставляется возможность:
● Выполнить фоновое задание с передачей параметров (метод ФоновыеЗадания.Выполнить()). После запуска фонового задания возвращается объект, описывающий запущенное фоновое задание (ФоновоеЗадание).
● Получить список фоновых заданий, соответствующих некоторому отбору (метод ФоновыеЗадания.ПолучитьФоновыеЗадания()) или найти фоновое задание по уникальному идентификатору фонового задания (ФоновыеЗадания.НайтиПоУникальномуИдентификатору()).
● Ожидать завершение одного (ФоновоеЗадание.ОжидатьЗавершенияВыполнения()) или нескольких (метод ФоновыеЗадания.ОжидатьЗавершенияВыполнения()) ранее запущенных фоновых заданий с указанием времени ожидания.
Более подробно рассмотрим все этапы.
Для запуска фонового задания необходима экспортируемая процедура или функция, описанная в не глобальном общем модуле, который доступен на сервере. Параметры вызываемого метода необходимо перечислить в специальном массиве параметров. При этом порядок следования параметров в методе должен в точности соответствовать порядку элементов массива: самый левый параметр соответствует элементу массива с индексом 0. Все значения параметров фонового задания должны поддерживать сериализацию. Затем передается ключ и описание запускаемого фонового задания. Ключ используется для обеспечения уникальности запускаемого фонового задания.
В качестве фонового задания будет использоваться экспортный метод общего модуля с именем ВыгрузитьДанные(), расположенный в серверном общем модуле ОбщийМодульФоновые:
Функция ВыгрузитьДанные(ОписаниеДанных, ПутьКФайлу) Экспорт // здесь выполняется собственно выгрузка данных КонецФункции
Для запуска фонового задания необходимо выполнить следующее:
ПараметрыВызова = Новый Массив; ПараметрыВызова.Добавить(ВыгружаемыеДанные); ПараметрыВызова.Добавить("c:tempdata.dat"); ЗаданиеВыгрузки = ФоновыеЗадания.Выполнить("ОбщийМодульФоновые.ВыгрузитьДанные", ПараметрыВызова, "ВыгрузкаДанных", "Выгрузка данных в файл на диске");
В качестве параметра ОписаниеДанных будет передано значение переменной ВыгружаемыеДанные, в качестве значения параметра ПутьКФайлу будет передана строка c:tempdata.dat. Для запускаемого фонового задания будет установлен ключ уникальности ВыгрузкаДанных и некоторое описание.
При запуске не выполняется ожидания завершения работы фонового задания. Вместо этого, после создания специального сеанса работы фонового задания и запуска метода фонового задания на выполнение, управление вернется в вызываемый код. При этом в качестве возвращаемого значения метода ФоновыеЗадания.Выполнить() будет получен объект, описывающий запущенное фоновое задание (типа ФоновоеЗадание). Этот объект будет помещен в переменную ЗаданиеВыгрузки.
С помощью описания фонового задания можно получить идентификатор фонового задания, который используется для поиска фонового задания (свойство УникальныйИдентификаторобъекта ФоновоеЗадание). При проверке состояния фонового задания (с помощью свойства фонового задания Состояние) следует помнить, что это состояние фиксируется на момент создания объекта ФоновоеЗадание и в дальнейшем не обновляется. Для проверки состояния необходимо перед каждой проверкой получать описание для проверяемого фонового задания:
ЗаданиеВыгрузки = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(Идентификатор);
При необходимости, работу конкретного экземпляра фонового задания можно прервать с помощью метода ФоновоеЗадание.Отменить(). При этом следует помнить, что после прерывания фонового задания необходимо реализовать «сборку мусора». Например, удалить временные файлы, которые могло порождать прерываемое фоновое задание.
После запуска фонового задания может потребоваться периодически проверять статус выполнения задания. Для этого предназначен метод ФоновоеЗадание.ОжидатьЗавершенияВыполнения(). В качестве параметра метода передается время, в течение которого ожидается изменение состояния фонового задания. В любом случае, не позднее, чем указанный таймаут, метод завершает свою работу и формирует объект ФоновоеЗадание, который описывает текущее состояние фонового задания (включая свойство Состояние).
Таким образом, ожидание завершения работы фонового задания можно выполнить следующим образом:
Пока Истина Цикл ЗаданиеВыгрузки = ЗаданиеВыгрузки.ОжидатьЗавершенияВыполнения(10); Если ЗаданиеВыгрузки.Состояние = СостояниеФоновогоЗадания.Активно Тогда // продолжаем ждать завершения Продолжить; Иначе // фоновое задание завершено Прервать; КонецЕсли; КонецЦикла;
В примере таймаут установлен в 10 секунд (параметр метода ОжидатьЗавершенияВыполнения()). Если за 10 секунд фоновое задание не завершило свою работу ‑ цикл ожидания завершения будет продолжен. Если фоновое задание перестало выполняться (перестало быть активным), то конкретная причина завершения будет понятна по анализу свойства ФоновоеЗадание.Состояние.
Следует отметить, что ожидать завершения работы можно не только для одного фонового задания. У менеджера фоновых заданий существует аналогичный метод (ФоновыеЗадания.ОжидатьЗавершенияВыполнения()). Разница заключается в том, что в качестве параметра метода передается массив объектов ФоновоеЗадание, завершение которых необходимо отслеживать.
Фоновое задание в процессе своей работы может формировать сообщения пользователю (с помощью объекта СообщениеПользователю). Эти сообщения могут быть получены с помощью метода ФоновоеЗадание.ПолучитьСообщенияПользователю(). Сообщения можно получать как во время работы фонового задания, так и после завершения работы задания.
18.2.3. Фоновое задание и расширения
При старте фонового задания в сеансе фонового задания будут подключены те расширения, которые были подключены в родительском сеансе. В тоже время имеется возможность запустить фоновое задание таким образом, чтобы в сеансе фонового задания были подключены все расширения, зарегистрированные для текущей информационной базы и текущего набора разделителей. Для этого следует использовать метод РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеСРасширениямиБазыДанных(). Однако, в некоторых сценариях может потребоваться запускать фоновое задание совсем без расширений конфигурации. Для этого следует использовать метод РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеБезРасширений().
18.3. Регламентные задания
Регламентные задания используются, когда необходимо выполнить определенные периодические или однократные действия в соответствии с расписанием.
Регламентные задания хранятся в информационной базе и создаются на основе метаданных регламентного задания, определенных в конфигурации. Метаданные задают такие параметры регламентного задания, как вызываемый метод, наименование, ключ, возможность использования, признак предопределенности и др. При создании регламентного задания дополнительно можно указать расписание (может быть указано в метаданных), значения параметров метода, имя пользователя, от имени которого должно выполняться регламентное задание, и др.
Создание и управление регламентными заданиями выполняется с помощью встроенного языка из любого соединения и разрешены только пользователям, имеющим административные права.
ПРИМЕЧАНИЕ. При работе в файловом варианте создавать и редактировать регламентные задания возможно без запуска планировщика заданий.
С регламентным заданием связан метод, который вызывается при выполнении регламентного задания. В качестве метода регламентного задания может выступать любая процедура или функция неглобального общего модуля, которую можно вызвать на сервере. Параметрами регламентного задания могут быть любые значения, которые разрешено передавать на сервер. Параметры регламентного задания должны в точности соответствовать параметрам той процедуры или функции, которую оно вызывает. Если методом регламентного задания является функция, то ее возвращаемое значение игнорируется.
Регламентное задание может иметь ключ ‑ любое прикладное значение. Ключ вводит ограничение на запуск регламентных заданий, т. к. в единицу времени среди регламентных заданий, связанных с одним и тем же объектом метаданных, может выполняться только одно регламентное задание с определенным значением ключа. Ключ позволяет группировать регламентные задания, связанные с одним и тем же объектом метаданных, по определенному прикладному признаку с тем, чтобы в рамках одной группы выполнялось не более одного регламентного задания.
При конфигурировании можно определить предопределенные регламентные задания. Предопределенные регламентные задания ничем не отличаются от обычных регламентных заданий, за исключением того, что их нельзя явно создавать и удалять. Если в метаданных регламентного задания установлен признак предопределенного регламентного задания, то при обновлении конфигурации в информационной базе автоматически будет создано предопределенное регламентное задание. Если признак предопределенности снят, то при обновлении конфигурации в информационной базе автоматически будет удалено предопределенное регламентное задание. Начальные значения свойств предопределенного регламентного задания (например, расписание) устанавливаются в метаданных. В дальнейшем при работе приложения их можно менять через соответствующие методы встроенного языка. Изменение свойств уже созданного предопределенного регламентного задания в метаданных не окажет влияния на реальные параметры этого задания в информационной базе. Предопределенные регламентные задания не имеют параметров.
Расписание регламентного задания определяет, в какие моменты времени регламентное задание должно быть запущено. Расписание позволяет:
● задавать дату и время начала и окончания выполнения задания;
● период выполнения;
● дни недели и месяцы, по которым нужно выполнять регламентное задание и др. (см. описание встроенного языка).
Примеры расписаний регламентных заданий:
Расписание | Значения параметров |
Каждый час, только один день | ПериодПовтораДней = 0ПериодПовтораВТечениеДня = 3600 |
Каждый день один раз в день | ПериодПовтораДней = 1ПериодПовтораВТечениеДня = 0 |
Один день, один раз | ПериодПовтораДней = 0 |
Через день один раз в день | ПериодПовтораДней = 2 |
Каждый час с 01.00 до 07.00 каждый день | ПериодПовтораДней = 1ПериодПовтораВТечениеДня = 3600ВремяНачала = 01.00ВремяКонца = 07.00 |
Каждую субботу и воскресенье в 09.00 | ПериодПовтораДней = 1ДниНедели = 6, 7ВремяНачала = 09.00 |
Каждый день одну неделю, неделя пропуска | ПериодПовтораДней = 1ПериодНедель = 2 |
В 01.00 один раз | ВремяНачала = 01.00 |
Последнее число каждого месяца в 9.00 | ПериодПовтораДней = 1ДеньВМесяце = -1ВремяНачала = 09.00 |
Пятое число каждого месяца в 9.00 | ПериодПовтораДней = 1ДеньВМесяце = 5ВремяНачала = 09.00 |
Вторая среда каждого месяца в 9.00 | ПериодПовтораДней = 1ДеньНеделиВМесяце = 2ДниНедели = 3ВремяНачала = 09.00 |
Можно проверять, выполняется ли задание для заданной даты (метод ТребуетсяВыполнение() объекта РасписаниеРегламентныхЗаданий). Регламентные задания всегда выполняются от имени определенного пользователя. Если пользователь регламентного задания не указан, то выполнение происходит с правами, которые определяются набором ролей, указанных в свойстве конфигурации ОсновныеРоли. В том случае, если в этом свойстве не указано ни одной роли, выполнение происходит без ограничения прав доступа.
Выполнение регламентных заданий происходит с использованием фоновых заданий. Когда планировщик определяет, что регламентное задание должно быть запущено, то автоматически на основе данного регламентного задания создается фоновое задание, которое и выполняет всю дальнейшую обработку. Если данное регламентное задание уже выполняется, то оно не будет запущено повторно, вне зависимости от его расписания.
Регламентные задания имеют возможность перезапуска. Это особенно актуально, когда метод регламентного задания должен быть гарантированно выполнен. Перезапуск регламентного задания осуществляется в том случае, когда оно завершено аварийно, либо когда рабочий процесс (в клиент-серверном варианте) или клиентский процесс (в файловом варианте), на котором выполнялось регламентное задание, завершен аварийно. В регламентном задании можно указать, сколько раз нужно его перезапускать (свойство Количество повторов при аварийном завершении), а также интервал между перезапусками (свойство Интервал повтора при аварийном завершении). После выполнения заданного количества перезапусков, попытки запуска прекращаются до момента, когда наступит очередное время старта регламентного задания (в соответствии с расписанием). При этом счетчик количества повторов сбрасывается и при аварийном завершении регламентного задания, процесс перезапуска начинается сначала.
При реализации метода перезапускаемого регламентного задания нужно учитывать, что при перезапуске его выполнение будет начато с начала, а не продолжено с момента аварийного завершения.
18.4. Особенности выполнения фоновых заданий в файловом и клиент-серверном вариантах
Механизмы выполнения фоновых заданий в файловом и клиент-серверном вариантах различаются.
18.4.1.1. Файловый вариант
Фоновые и регламентные задания выполняются клиентскими приложениями или расширением веб-сервера. Фоновые задания выполняются на том клиентском приложении, которое инициировало запуск фонового задания. Фоновые задания исполняются последовательно, т. е. на одном клиентском приложении не может одновременно выполняться два фоновых задания. В случае работы через веб-сервер, для каждой информационной базы, доступ к которой осуществляется через этот веб-сервер, организовано последовательное выполнение фоновых и регламентных заданий.
Поведение фоновых и регламентных заданий в файловом варианте имеет следующие особенности:
● Информация о фоновых заданиях, вызванных с помощью методов языка или выполняющих отчеты, доступна только в том клиентском приложении, которое их выполняло. Информация не сохраняется после завершения работы клиентского приложения.
● Информация о фоновых заданиях, инициированных регламентными заданиями, доступна на всех клиентских приложениях и сохраняется между запусками.
● Регламентные задания выполняются только одним клиентским приложением. Имеется возможность запретить запуск регламентных заданий определенным клиентским приложением или указать, что какое-либо клиентское приложение принудительно назначается исполнителем регламентных заданий. Такое управление осуществляется с помощью:
● Параметра командной строки /AllowExecuteScheduledJobs для толстого и тонкого клиентских приложений.
● Атрибута allowexecutescheduledjobs элемента point файла публикации default.vrd (см. здесь) в случае публикации информационной базы на веб-сервере.
● Регламентные задания выполняются первым, по порядку запуска, клиентским приложением, у которого не указан запрет выполнения регламентных заданий. После завершения сеанса этого клиентского приложения, выполнение переходит к какому-либо из оставшихся запущенными клиентских приложений. Если запускается клиентское приложение с явным указанием на необходимость исполнения регламентных заданий, то регламентные задания начинают выполняться этим клиентским приложением, независимо от наличия других клиентских приложений (включая расширения веб-сервера).
● Регламентные задания выполняются расширением веб-сервера до тех пор, пока расширение веб-сервера обслуживает хотя бы один клиентский сеанс.
● Регламентные задания обрабатываются один раз в 60 секунд.
● Инициализация планировщика фоновых заданий выполняется через 60 секунд после старта клиентского приложения или после попытки запустить первое фоновое задание. До момента запуска планировщика фоновых заданий в синхронном режиме выполняются следующие операции: поиск в динамическом списке, построение отчетов и поиск для ввода по строке.
● Инициализация механизма планировщика регламентных заданий выполняется через 60 секунд после запуска механизма планировщика фоновых заданий. Следовательно, регламентные задания прикладного решения начинают выполняться максимум через 120 секунд после запуска клиентского приложения.
● Выполняется принудительное завершение фоновых заданий, которые не завершились в течение 30 секунд после завершения работы клиентского приложения. В журнале регистрации в этом случае фиксируется событие Фоновое задание. Принудительное завершение (_$Job$_.Terminate).
● Не поддерживается работа регламентных заданий в файловом варианте информационной базы в сеансе, который получен с использованием automation-сервера «1С:Предприятия» или COM-соединения. Если в таком сеансе создаются фоновые задания, они размещаются в очереь, но запуск таких заданий выполнен не будет.
18.4.1.2. Клиент-серверный вариант
В клиент-серверном варианте для выполнения фоновых заданий используется планировщик заданий, который физически находится в менеджере кластера. Планировщик получает наименее загруженный рабочий процесс для всех поставленных в очередь на выполнение фоновых заданий и использует его для выполнения соответствующего фонового задания. Рабочий процесс выполняет задание и уведомляет планировщик о результатах выполнения.
В клиент-серверном варианте имеется возможность блокирования выполнения регламентных заданий. Блокирование выполнения регламентных заданий происходит в следующих случаях:
● На информационную базу установлена явная блокировка регламентных заданий. Блокировка может быть установлена через консоль кластера.
● На информационную базу установлена блокировка начала сеансов. Блокировка может быть установлена через консоль кластера.
● Из встроенного языка вызван метод УстановитьМонопольныйРежим() с параметром Истина.
● В некоторых других случаях (например, при обновлении конфигурации базы данных).
18.5. Создание метаданных регламентного задания
Перед тем как создать регламентное задание в информационной базе с помощью встроенного языка, необходимо создать для него объект конфигурации.
Для создания объекта конфигурации регламентного задания в ветке Общие дерева конфигурации для ветки Регламентные задания нужно выполнить команду Добавить.
Регламентное задание обладает рядом свойств, которые описаны ниже.
Имя метода ‑ указывается имя метода регламентного задания.
Ключ ‑ указывается произвольное строковое значение, которое будет использовано в качестве ключа регламентного задания.
Расписание ‑ указывается расписание регламентного задания. Для формирования расписания следует перейти по ссылке Открыть и в открывшейся форме расписания установить нужные значения.
На закладке Общее указывается дата начала и завершения задания и режим повтора.
Рис. 462. Общее расписание
На закладке Дневное указывается дневное расписание задания.
Рис. 463. Дневное расписание
В расписании можно указать:
● время начала и окончания задания;
● время завершения задания, после которого оно будет принудительно завершено;
● период повтора задания;
● продолжительность паузы между повторами;
● продолжительность выполнения.
Допускается указание произвольного сочетания условий.
На закладке Недельное указывается недельное расписание задания.
Рис. 464. Недельное расписание
Нужно установить флажки по тем дням недели, по которым задание будет выполняться. Если требуется повторять задание, указать интервал повтора в неделях. Например, задание выполняется через 2 недели, значение повтора ‑ 2.
В том случае, задано недельное расписание и значение свойства Повторять каждые больше 1, то при определении границ недели будет учитываться свойство Первый день недели, заданный в региональных настройках информационной базы (подробнее см. здесь).
На закладке Месячное указывается месячное расписание задания.
Рис. 465. Месячное расписание
Нужно установить флажки по тем месяцам, в которых задание будет выполняться. При необходимости можно указать конкретный день (месяца или недели) выполнения с начала месяца/недели или конца.
Использование ‑ если установлено, то задание будет выполняться согласно расписанию.
Предопределенное ‑ если установлено, то задание является предопределенным.
Количество повторов при аварийном завершении ‑ указывает количество повторов при аварийном завершении.
Интервал повтора при аварийном завершении ‑ указывает интервал повтора при аварийном завершении.
Пример создания фонового задания «Обновление индекса полнотекстового поиска»:
ФоновыеЗадания.Выполнить("ОбновлениеИндексаПолнотекстовогоПоиска");
Пример создания регламентного задания «Восстановление последовательностей»:
Расписание = Новый РасписаниеРегламентногоЗадания; Расписание.ПериодПовтораДней = 1; Расписание.ПериодПовтораВТечениеДня = 0; Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание("ВосстановлениеПоследовательностей"); Задание.Расписание = Расписание; Задание.Записать();
В системе 1С:Предприятие 8.3 предусмотрено довольно много способов повышения производительности и быстродействия. Один из вариантов – настройка регламентных и фоновых заданий.
Для начала кратко определим, что это такое, для чего они нужны и за что отвечают:
- Регламентные задания в 1С – это механизмы, заложенные в конфигурацию, указывающие на необходимость выполнять определенных задач по установленному расписанию. Такое задание в обязательном порядке порождает фоновое.
- Фоновые задания в 1С 8.3 – это действия, производимые программой 1С незаметно для работающего в ней. Отслеживают их исполнение только по журналу регистрации. Особенностью такого задания является то, что при его выполнении не блокируется работа пользователя, он может продолжать вносить и редактировать данные, даже если процедура запущена.
Приглашаем на
бесплатный вебинар!
06 июня в 11:00 мск
1 час
Как настроить регламентное задание и фоновое
Рассматриваемые нами процессы начинают исполняться автоматом после запуска 1С, при этом они используют огромное количество ресурсов и замедляют работу. Чтобы оптимизировать работу, по согласованию с пользователем конкретной информационной базы надо решить, какие задания нужно отключить, а какие оставить в автоматическом запуске при загрузке.
В программе 1С 8.3 список заданий находится в «Администрирование-Настройки программы-Обслуживание».
В «Обслуживание-Регламентные операции» находим ссылку на наши операции.
Перед нами список заданий, разделенных по виду на отдельных вкладках.
У Регламентных заданий указывается:
- Наименование;
- Состояние (выполняется или выполнено);
- Дата окончания.
У Фоновых заданий:
- Состояние (выполняется или выполнено);
- Наименование;
- Начало;
- Окончание.
Рассмотрим регламентную операцию «Загрузка курсов валют». Заходим на соответствующую вкладку. С заданиями можно осуществлять следующие действия:
- Включить – поставить флажок «включено»;
- Выключить – снять флажок «включено», затем «Записать и закрыть». Так можно отключить задания, которые не представляются важными, и это значительно увеличит скорость работы в программе 1С;
- Настроить расписание исполнения.
Виды расписаний
Общее – указываем дату начала/окончания, а также периодичность повторений в днях.
Дневное – указав время начала, время окончания, завершать после какого времени, а также повторять через, повторять с паузой, останавливать через. Время указывается в секундах.
Недельное – на этой вкладке галочками мы отмечаем дни недели, а также количество повторений.
Месячное – галочками отмечают месяцы, в которые надо запускать задания обоих видов.
Добавление Регламентного задания
Для добавления в информационную базу такого вида задания, надо открыть Конфигуратор. Для создания задания пользователь должен обладать правами администратора.
Далее выбираем «Конфигурация-Открыть конфигурацию». Затем открываем «Общие-Регламентные задания», нажимаем правой кнопкой мыши, появляется окошко «Добавить». Выбираем его.
Заполняем задание:
- В графе «Имя модуля» указывается процедура для исполнения. В ней прописаны все подробности и нюансы работы;
- Для отключения или включения задания необходимо установить или удалить флажок в поле «Использование»;
- Указываем «Предопределенность». Задания с этой характеристикой запускаются автоматом. Если не поставить галочку, то надо будет запускать их дополнительно;
- Указываем число повторений и длину интервалов между ними при аварийном завершении работы.
Также здесь мы можем настроить расписание задания. Нажимаем на кнопку «Расписание (Открыть)» и переходим к его заполнению.
К примеру, нам нужно выполнять наше задание с 1 по 30 сентября один раз в день. Также мы можем настроить расписание исполнения Регламентного задания, как уже было описано выше.
Сегодня мы познакомились с Регламентными и Фоновыми заданиями в программе 1С 8.3, узнали, как добавить новое задание или настроить существующее, а также отключить выполнение ненужных задач. В заключение хочется отметить, что оба видов заданий в 1С очень удобны для пользователя, так как выполняются автоматом, по четко заданному сценарию, не отвлекая специалиста от работы, и тем самым увеличивают производительность труда.
Фоновые задания
Иногда требуется выполнить какую-нибудь длительную операцию без блокирования интерфейса. То есть пользователь нажал кнопку, запустилась какая-нибудь длительная процедура, а в этом время пользователь может делать что-нибудь другое в программе. Для этого можно использовать механизм фоновых заданий.
Фоновые задания запускаются асинхронно (без ожидания завершения), в отдельном потоке. Фоновые задания можно запустить только на сервере. Для примера, представим что есть некий список электронных адресов, на который нужно выполнить рассылку по электронной почте. В списке может быть много адресов, да и отправка одного письма выполняется какое-то время. Поэтому хотелось бы запустить рассылку и продолжить дальше работать с программой.
Чтобы запустить фоновое задание используется метод Выполнить менеджера фоновых заданий. Первым параметром передается имя общего модуля и имя метода. Указанный метод должен находиться в общем модуле и быть экспортным.
ИмяМетода = "МодульФоновыхЗаданий.ВыполнитьРассылку"; ФоновыеЗадания.Выполнить(ИмяМетода); //код из серверного общего модуля МодульФоновыхЗаданий Процедура ВыполнитьРассылку() Экспорт //код для выполнения рассылки КонецПроцедуры
В результате будет запущено фоновое задание, которое выполнит метод ВыполнитьРассылку из общего модуля МодульФоновыхЗаданий. Во время выполнения фонового задания интерфейс пользователя не будет заблокирован.
Если сейчас трижды запустить одно фоновое задание, то оно будет запущено три раза и три раза выполнит одно и то же действие. Чтобы избежать повторного запуска фонового задания, если оно уже было запущено можно использовать Ключ фонового задания. Ключ передается третьим параметром в метод Выполнить:
ИмяМетода = “МодульФоновыхЗаданий.ВыполнитьРассылку”;
Ключ = “Рассылка”;
ФоновыеЗадания.Выполнить(ИмяМетода,, Ключ);
В результате при первом выполнении данного кода будет запущено фоновое задание с ключом «Рассылка». Если не дождавшись выполнения текущего фонового задания попробовать запустить его еще раз, то будет выброшено исключение «Задание с таким значением ключа уже выполняется». Если указать другое значение ключа, то оба фоновых задания будут выполняться одновременно.
Если у фоновых заданий с одним значением ключа не совпадают методы для выполнения, то такие задания могут быть запущены одновременно.
Стоит отметить, что в качестве метода для фонового задания можно использовать как процедуру, так и функцию. Возвращаемый результат функции будет проигнорирован. В качестве метода фонового задания нельзя использовать методы глобальных общих модулей.
Параметры фонового задания
При запуске фонового задания можно передать параметры в метод общего модуля. Например, добавим в процедуру ВыполнитьРассылку два параметра:
Процедура ВыполнитьРассылку(ПервыйПараметр, ВторойПараметр) Экспорт //код для выполнения рассылки КонецПроцедуры
При запуске фонового задания вторым параметром нужно перадать массив параметров. Первый элемент массива будет передан в первый параметр, второй — во второй и т.д.
ИмяМетода = “МодульФоновыхЗаданий.ВыполнитьРассылку”;
Ключ = “Рассылка”;//параметры
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(“Первый параметр”);
МассивПараметров.Добавить(“Второй параметр”);ФоновыеЗадания.Выполнить(ИмяМетода, МассивПараметров, Ключ);
Если количество параметров не будет совпадать, то фоновое задание не будет выполнено.
Фоновые задания в файловом и клиент-серверном варианте
Механизм выполнения фоновых заданий отличается в файловом и клиент-серверном варианте.
В файловом варианте фоновые задания выполняются на том клиентском приложении, которое его запустило. Одновременно может выполняться только одно фоновое задание, остальные фоновые задания встают в очередь.
В клиент-серверном варианте фоновые задания выполняются планировщиком заданий, который находится в менеджере кластера. Планировщик заданий подбирает наименее загруженный рабочий процесс сервера 1С и выполняет фоновое задание на нем.
И в файловом и клиент-серверном варианте фоновое задание это отдельный системный сеанс, который выполняется от имени того пользователя, кто создал задание.
Фоновое задание с ожиданием результата
Если требуется дождаться результата выполнения фонового задания, то можно воспользоваться тем, что метод Выполнить возвращает объект Фоновое задание. А у этого объекта есть метод ОжидатьЗавершенияВыполнения, который остановит поток выполнения, пока не изменится состояние фонового задания. Фоновое задание может быть в четырех состояниях:
– Активно — задание запущено на выполнение
– Завершено — задание успешно выполнено
– Завершено аварийно — возникла ошибка при выполнении задания
– Отменено — задание было отменено
После изменения состояния фонового задания метод ОжидатьЗавершенияВыполнения вернет обновленное фоновое задание, у которого можно анализировать свойство Состояние, чтобы узнать результат выполнения:
ИмяМетода = "МодульФоновыхЗаданий.ВыполнитьРассылку"; Ключ = "Рассылка"; //параметры МассивПараметров = Новый Массив; МассивПараметров.Добавить("Первый параметр"); МассивПараметров.Добавить("Второй параметр"); ФонЗад = ФоновыеЗадания.Выполнить(ИмяМетода, МассивПараметров, Ключ); //останавливаем поток до окончания выполнения фонового задания ФонЗад = ФонЗад.ОжидатьЗавершенияВыполнения(); //анализируем состояние фонового задания Если ФонЗад.Состояние = СостояниеФоновогоЗадания.Завершено Тогда Сообщить("Выполнено успешно"); ИначеЕсли ФонЗад.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда Сообщить("Ошибка при выполнении " + ФонЗад.ИнформацияОбОшибке.Описание); ИначеЕсли ФонЗад.Состояние = СостояниеФоновогоЗадания.Отменено Тогда Сообщить("Задание отменено"); КонецЕсли;
Метод Выполнить вернул фоновое задание, состояние которого было равно Активно. Состояние автоматически не обновляется. Для проверки изменения состояния фонового задания нужно заново получить фоновое задание. В данном примере оно было получено методом ОжидатьЗавершенияВыполнения.
Пауза через фоновое задание
В метод ОжидатьЗавершенияВыполнения параметром можно передать количество секунд. Выполнение кода продолжится или по истечении этого времени или сразу после изменения состояния фонового задания. Можно воспользоваться данным методом для возможности оставить выполнение кода на указанное количество секунд. В общий модуль добавим следующую процедуру:
Процедура Пауза(Таймаут) Экспорт ТекСеанс = ПолучитьТекущийСеансИнформационнойБазы(); ФонЗад = ТекСеанс.ПолучитьФоновоеЗадание(); //в сеансе фонового задания в переменной ФонЗад будет само фоновое задание //а в клиентском сеансе будет Неопределено Если ФонЗад = Неопределено Тогда МассивПараметров = Новый Массив; МассивПараметров.Добавить(Таймаут); ФонЗад = ФоновыеЗадания.Выполнить("МодульФоновыхЗаданий.Пауза", МассивПараметров); КонецЕсли; ФонЗад.ОжидатьЗавершенияВыполнения(Таймаут); КонецПроцедуры
Параметром принимаем количество секунд для паузы, затем определяем чей это сеанс. Если клиентский, то запускаем фоновое задание и ждем его завершения. Если это сеанс фонового задания, то просто ждем его завершения.
Вызов паузы на 5 секунд:
МодульФоновыхЗаданий.Пауза(5);
Преимущество такого метода в том, что на время паузы не загружается процессор.
Оповещение о выполнении фонового задания
Иногда требуется не просто запустить выполнение фонового задания, а оповестить пользователя о результатах выполнения. Для этого можно использовать следующий алгоритм действий:
1. Запускаем фоновое задание и сохраняем его уникальный идентификатор
2. С определенной периодичностью находим фоновое задание по идентификатору с помощью метода НайтиПоУникальномуИдентификатору и проверяем его состояние
//переменная модуля формы для сохранения //идентификатора фонового задания &НаКлиенте Перем УИД; &НаКлиенте Процедура Команда1(Команда) //запускаем фоновое задание УИД = ЗапуститьФоновоеЗадание(); //подключаем обработчик ожидания ПодключитьОбработчикОжидания("ПроверитьВыполнение", 1); КонецПроцедуры &НаСервере Функция ЗапуститьФоновоеЗадание() ИмяМетода = "МодульФоновыхЗаданий.ВыполнитьРассылку"; Ключ = "Рассылка"; //параметры МассивПараметров = Новый Массив; МассивПараметров.Добавить("Первый параметр"); МассивПараметров.Добавить("Второй параметр"); ФонЗад = ФоновыеЗадания.Выполнить(ИмяМетода, МассивПараметров, Ключ); //возвращаем идентификатор фонового задания Возврат ФонЗад.УникальныйИдентификатор; КонецФункции //данная процедура вызывается платформой раз в секунду &НаКлиенте Процедура ПроверитьВыполнение() Экспорт Если ЗаданиеВыполнено(УИД) Тогда //оповещаем пользователя ПоказатьОповещениеПользователя("Задание выполнено"); //и отключаем обработчик ожидания ОтключитьОбработчикОжидания("ПроверитьВыполнение"); КонецЕсли; КонецПроцедуры &НаСервере Функция ЗаданиеВыполнено(УИД) //находим фоновое задание по идентификатору ФонЗад = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(УИД); //проверяем статус Если ФонЗад.Состояние = СостояниеФоновогоЗадания.Завершено Тогда Возврат Истина; ИначеЕсли ФонЗад.Состояние = СостояниеФоновогоЗадания.Активно Тогда //еще не выполнилось Возврат Ложь; Иначе //отменено или была ошибка Возврат Истина; КонецЕсли; КонецФункции
Здесь был использован метод ПодключитьОбработчикОжидания, который вызывает процедуру, указанную в первом параметре через время, указанное во втором параметре. Затем вызов процедуры был отменен через метод ОтключитьОбработчикОжидания.
Отмена выполнения фонового задания
Для отмены фонового задания можно использовать метод Отменить самого фонового задания:
ИмяМетода = “МодульФоновыхЗаданий.ВыполнитьРассылку”;
Ключ = “Рассылка”;//параметры
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(“Первый параметр”);
МассивПараметров.Добавить(“Второй параметр”);//запускаем
ФонЗад = ФоновыеЗадания.Выполнить(ИмяМетода, МассивПараметров, Ключ);
//отменяем
ФонЗад.Отменить();
Сообщения из фонового задания
Фоновое задание выполняется на сервере, поэтому если в нем использовать сообщения пользователю, то их никто не увидит. Однако у фонового задания есть метод ПолучитьСообщенияПользователю, который позволяет получить все сообщения из фонового задания. Для примера добавим в общий модуль следующую процедуру:
Процедура СообщенияИзФона() Экспорт Сообщить("Сообщение из фонового задания"); КонецПроцедуры
Выполним ее через фонового задание с получением всех сообщений и выведем полученные сообщения на экран:
ИмяМетода = "МодульФоновыхЗаданий.СообщенияИзФона"; Ключ = "СообщенияИзФона"; ФонЗад = ФоновыеЗадания.Выполнить(ИмяМетода,, Ключ); ФонЗад.ОжидатьЗавершенияВыполнения(); //параметр Истина удаляет все полученные сообщения СообщенияИзФона = ФонЗад.ПолучитьСообщенияПользователю(Истина); Для Каждого Сообщ Из СообщенияИзФона Цикл Сообщ.Сообщить(); КонецЦикла;
Через сообщения можно организовать получение прогресса выполнения фонового задания. Добавим в общий модуль следующие процедуры:
Процедура СообщенияИзФона() Экспорт Для Сч = 1 По 10 Цикл Сообщить(Сч); Пауза(1); КонецЦикла; КонецПроцедуры Процедура Пауза(Таймаут) Экспорт ТекСеанс = ПолучитьТекущийСеансИнформационнойБазы(); ФонЗад = ТекСеанс.ПолучитьФоновоеЗадание(); //в сеансе фонового задания в переменной ФонЗад будет само фоновое задание //а в клиентском сеансе будет Неопределено Если ФонЗад = Неопределено Тогда МассивПараметров = Новый Массив; МассивПараметров.Добавить(Таймаут); ФонЗад = ФоновыеЗадания.Выполнить("МодульФоновыхЗаданий.Пауза", МассивПараметров); КонецЕсли; ФонЗад.ОжидатьЗавершенияВыполнения(Таймаут); КонецПроцедуры
И запустим фоновое задание на выполнение, с периодическим получением сообщений:
//переменная модуля формы для сохранения //идентификатора фонового задания &НаКлиенте Перем УИД; //процент выполнения задания &НаКлиенте Перем ПроцентВыполнения; &НаКлиенте Процедура Команда1(Команда) //запускаем фоновое задание УИД = ЗапуститьФоновоеЗадание(); //подключаем обработчик ожидания ПодключитьОбработчикОжидания("ПроверитьВыполнение", 1); КонецПроцедуры &НаСервере Функция ЗапуститьФоновоеЗадание() ИмяМетода = "МодульФоновыхЗаданий.СообщенияИзФона"; Ключ = "СообщенияИзФона"; ФонЗад = ФоновыеЗадания.Выполнить(ИмяМетода,, Ключ); //возвращаем идентификатор фонового задания Возврат ФонЗад.УникальныйИдентификатор; КонецФункции //данная процедура вызывается платформой раз в секунду &НаКлиенте Процедура ПроверитьВыполнение() Экспорт Если ЗаданиеВыполнено(УИД, ПроцентВыполнения) Тогда //оповещаем пользователя ПоказатьОповещениеПользователя("Задание выполнено"); //и отключаем обработчик ожидания ОтключитьОбработчикОжидания("ПроверитьВыполнение"); Иначе //выводим процент выполнения фонового задания Состояние("Задание выполняется", ПроцентВыполнения*10); КонецЕсли; КонецПроцедуры &НаСервере Функция ЗаданиеВыполнено(УИД, ПроцентВыполнения) //находим фоновое задание по идентификатору ФонЗад = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(УИД); //проверяем статус Если ФонЗад.Состояние = СостояниеФоновогоЗадания.Завершено Тогда Возврат Истина; ИначеЕсли ФонЗад.Состояние = СостояниеФоновогоЗадания.Активно Тогда //получаем сообщения СообщенияИзФона = ФонЗад.ПолучитьСообщенияПользователю(Истина); Для Каждого Сообщ Из СообщенияИзФона Цикл ПроцентВыполнения = Число(Сообщ.Текст); КонецЦикла; Возврат Ложь; Иначе //отменено или была ошибка Возврат Истина; КонецЕсли; КонецФункции
В результате в процессе выполнения фонового задания можно будет увидеть окно состояния с прогрессом выполнения:
Многопоточность через фоновые задания
С помощью фоновых заданий можно выполнить какую-то обработку в несколько потоков. Например, нужно во всем справочнике товаров увеличить цену на 10%. Можно разбить все товары на несколько частей и каждую часть обработать в отдельном потоке:
Процедура МногопоточнаяОбработка() Экспорт ЗапросТоваров = Новый Запрос; ЗапросТоваров.Текст = "ВЫБРАТЬ | Товары.Ссылка КАК Ссылка |ИЗ | Справочник.Товары КАК Товары |ГДЕ | НЕ Товары.ЭтоГруппа"; МассивТоваров = ЗапросТоваров.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); КоличествоТоваров = МассивТоваров.Количество(); КоличествоПотоков = 4; РазмерПорции = Цел(КоличествоТоваров/КоличествоПотоков); МассивЗаданий = Новый Массив; Для Сч = 0 По КоличествоПотоков-1 Цикл Если Сч = КоличествоПотоков-1 Тогда НачИнд = Сч * РазмерПорции; КонИнд = КоличествоТоваров-1; Иначе НачИнд = Сч * РазмерПорции; КонИнд = Сч * РазмерПорции + РазмерПорции-1; КонецЕсли; ИмяМетода = "МодульФоновыхЗаданий.ИзменитьЦену"; МассивПараметров = Новый Массив; МассивПараметров.Добавить(МассивТоваров); МассивПараметров.Добавить(НачИнд); МассивПараметров.Добавить(КонИнд); МассивПараметров.Добавить(1.1); ФонЗад = ФоновыеЗадания.Выполнить(ИмяМетода, МассивПараметров); МассивЗаданий.Добавить(ФонЗад); КонецЦикла; Если МассивЗаданий.Количество() > 0 Тогда ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий); КонецЕсли; КонецПроцедуры Процедура ИзменитьЦену(МассивТоваров, НачИнд, КонИнд, Наценка) Экспорт Для Сч = НачИнд По КонИнд Цикл ТоварОбъект = МассивТоваров[Сч].ПолучитьОбъект(); ТоварОбъект.Цена = ТоварОбъект.Цена * Наценка; ТоварОбъект.ОбменДанными.Загрузка = Истина; ТоварОбъект.Записать(); КонецЦикла; КонецПроцедуры
Здесь мы использовали метод ОжидатьЗавершения, но уже не у самого фонового задания, а у менеджера фоновых заданий. Параметром передали массив тех фоновых заданий, завершение которых нужно дождаться. У менеджера фоновых заданий тоже есть метод ОжидатьЗавершенияВыполнения, в который помимо массива заданий можно передать таймаут, аналогично одноименному методу у фонового задания. Даже если в методе ОжидатьЗавершенияВыполнения не указывать таймаут, то он в любом случае вернет массив всех обновленных фоновых заданий, после изменения статуса хотя бы у одного задания. Так как нам нужно дождаться завершения всех заданий, то был использован метод ОжидатьЗавершения.
Стоит отметить, что в одном фоновом задании можно запустить другое фоновое задание. То есть можно было запустить одно фоновое задание, в нем распараллелить выполнение на четыре фоновых задания, дождаться их выполнения и оповестить пользователя о завершении.
В силу ограничений выполнения фоновых заданий в файловом варианте многопоточную обработку данных можно реализовать только в клиент-серверном варианте.
Получить фоновые задания
Метод ПолучитьФоновыеЗадания позволяет получить список всех фоновых заданий, сохраненных в базе данных. Выполненные фоновые задания хранятся в течении суток, но не более 1000 заданий. Соответственно метод ПолучитьФоновыеЗадания вернет как текущие фоновые задания (выполняются в данный момент), так и завершившиеся в течении суток задания.
ВсеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(); Для Каждого Задание Из ВсеЗадания Цикл Сообщить(Задание.Наименование); Сообщить(Задание.Состояние); КонецЦикла;
Нужно учитывать, что сюда также попадут системные фоновые задания, которые выполняет сама платформа.
Параметром можно передать структуру с отбором, чтобы получить только нужные фоновые задания:
//только активные фоновые задания
ОтборЗаданий = Новый Структура;
ОтборЗаданий.Вставить(“Состояние”, СостояниеФоновогоЗадания.Активно);
ВсеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(ОтборЗаданий);//задания запущенные после 1 мая 2021
ОтборЗаданий = Новый Структура;
ОтборЗаданий.Вставить(“Начало”, Дата(2021,5,1));
ВсеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(ОтборЗаданий);//с отбором по имени метода
ОтборЗаданий = Новый Структура;
ОтборЗаданий.Вставить(“ИмяМетода”, “МодульФоновыхЗаданий.СообщенияИзФона”);
ВсеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(ОтборЗаданий);
Отбор можно устанавливать по следующим свойствам:
– УникальныйИдентификатор
– Ключ
– Состояние
– Начало
– Конец
– Наименование
– ИмяМетода
– РегламентноеЗадание
Можно сразу по нескольким свойствам.
Смотрите также:
Электронный учебник по программированию в 1С
Рекомендации по изучению программирования 1С с нуля
Игра “Кто хочет стать миллионером?” с вопросами на определенную тематику (язык программирования JavaScript, английские, немецкие, французские, испанские, португальские, нидерландские, итальянские слова, электробезопасность, промышленная безопасность, бокс и т.п.), написанная на 1С
Программирование в 1С 8.3 с нуля — краткий самоучитель
Комплексная подготовка программистов 1С:Предприятие 8.2
Сайты с уроками программирования и со справочниками
Youtube-каналы с уроками программирования
Сайты для обучения программированию
Лекции и уроки
Механизм регламентных и фоновых заданий позволяет выполнять определенные задачи по расписанию. В данной статье я на примере записи лога в регистр сведений покажу, как можно настроить регламентные и фоновые задания. Ну и без теории, конечно же, не обойдется! 🙂
Содержание
Чем отличаются регламентные задания от фоновых?
Регламентные задания – это отдельный механизм платформы, позволяющий автоматически выполнять какие-то действия по заданному расписанию. Регламентные задания можно создать и настроить в конфигураторе, в ветке метаданных “Общие”. На основе добавленных в конфигураторе регламентных заданий можно средствами языка 1С создавать отдельные экземпляры регламентных заданий с разными настройками, которые будут храниться в информационной базе.
Фоновые задания – это объекты языка 1С, которые служат для асинхронного выполнения прикладных задач. Они запускаются в отдельных системных сеансах, могут порождать подчиненные фоновые задания, и тем самым позволяют реализовать параллельную обработку данных.
Регулярно встречаю тиражируемую с сайта на сайт информацию, что фоновые задания – это объект, порождаемый регламентными заданиями. Это не так. Фоновые задания действительно могут создаваться на основе регламентных. Но могут быть созданы и полностью независимо при помощи встроенного языка.
Создание и настройка регламентного задания
Разобраться с регламентными заданиями проще всего на примере, поэтому давайте перейдем к практике! Вне зависимости от того, клиент-серверный вариант базы, или файловый, последовательность действий будет одна и та же. Об особенностях файлового режима смотрите в конце данной статьи.
В конфигураторе откроем ветку метаданных Общее, перейдем к пункту Регламентные задания, и добавим новое задание. Пусть наше задание просто добавляет запись в регистр сведений “ЛогРеглЗадания”. Код, который выполняет запись, не принципиален, и рассматривать его в данной статье мы не будем.
В случае, если регламентное задание завершится с ошибкой, платформа предусматривает возможность повторной попытки выполнить это задание. Например, мы можем пытаться связаться с внешним интернет-сайтом, и в случае, если он не отвечает с первого раза, выполнить еще несколько попыток – на случай перебоев в сетевом соединении.
Количество повторов при аварийном завершении – этот параметр указывает платформе, сколько раз вызвать регламентное задание в случае неудачи, в рамках одного запуска по расписанию. Если за указанное количество повторов регламентное задание так и не завершилось успехом, его выполнение прекращается, но следующий запуск по расписанию снова будет снова предусматривать возможность повторов.
Интервал повтора при аварийном завершении – время в секундах, через которое платформа будет пытаться повторно выполнить регламентное задание.
Как это работает? Рассмотрим на примере. Мы настроили расписание задания – каждый день, каждый час. Количество попыток 2, интервал – 30 секунд. Предположим, задание прервалось по ошибке. Платформа через 30 секунд попробует снова, и если будет ошибка, подождет еще 30 секунд, и попытается выполнить задание последний раз. После этого, вне зависимости от того, отработало ли регл. задание или снова была ошибка, через 1 час согласно расписанию будет новый цикл попыток выполнить регламентное задание.
В поле Имя метода нужно указать имя экспортной процедуры серверного общего модуля. Изначально если имя метода не указано, при нажатии на кнопку увеличительного стекла будет открыт диалог выбора общего модуля, в котором далее будет автоматически создан экспортный метод.
Если же нажать на кнопку с многоточием, то будет открыт другой диалог – выбор обработчика события. В этом окне мы можем выбрать подходящую процедуру из уже существующих.
Отметим флажки Использование и Предопределенное, и нажмем гиперссылку “Открыть” в строке Расписание. В открывшемся диалоговом окне можно достаточно гибко настроить расписание, по которому должно работать регламентное задание. В зависимости от настроек на разных закладках, в отдельном поле формируется понятное текстовое пояснение, например:
Выполнять: c 1 января 2022 г. каждый день; с 20:00:00 каждые 10 секунд
Чтобы понять, как вам лучше настроить расписание, лучше самостоятельно изучить закладки и поиграть с параметрами, например, выключить выполнение задания в выходные дни, или настроить выполнение раз в квартал.
Итак, мы создали объект метаданных Регламентное задание. Но это по сути только образец, эталон, на основе которого в информационной базе будут создаваться отдельные экземпляры. Эти экземпляры регламентных заданий хранятся непосредственно в информационной базе.
Что такое предопределенные регламентные задания?
В случае, если для регламентного задания указать признак “Предопределенное”, в информационной базе будет создан предопределенный экземпляр этого задания, который нельзя удалить или создать программно. В остальном он не отличается от других регламентных заданий, которые созданы в информационной базе. Если в объекте метаданных снять флажок “Предопределенное”, то существующее в информационной базе предопределенное регламентное задание будет автоматически удалено.
Если вы хотите, чтобы регламентное задание сразу вступило в строй и начало работать автоматически, следует включить флажок “Предопределенное”. Если этого не сделать, то для создания и настройки такого регламентного задания можно воспользоваться обработкой “Консоль заданий”, либо создавать экземпляр этого регламентного задания средствами языка 1С.
Важный нюанс. Регламентные задания после создания в конфигураторе, можно настраивать в режиме 1С Предприятие – указать другое расписание, отметить или отключить использование, задать параметры выполнения. Изменения регламентного задания в пользовательском режиме никак не повлияют на настройки этого регламентного задания в метаданных.
Как создать регламентное задание программно?
За программную работу с регламентными заданиями отвечает свойство глобального контекста РегламентныеЗадания – это специальный объект с типом МенеджерРегламентныхЗаданий.
Объекты регламентных заданий можно создавать только на основе существующих в метаданных регламентных заданий. Рассмотрим пример:
Расписание = Новый РасписаниеРегламентногоЗадания; Расписание.ПериодПовтораДней = 1; Расписание.ПериодПовтораВТечениеДня = 3600; Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание("ЗаписатьВЛог"); Задание.Расписание = Расписание; Задание.Записать();
В примере мы создаем объект задания на основе метаданных регламентного задания “ЗаписатьВЛог” и объекта расписание. Расписание в свою очередь – это объект языка, который аналогичен рассмотренному выше окну расписания – и все настройки, которые делаются в этом окне интерактивно, можно задать программно средствами языка 1С.
Второй вариант использования метода СоздатьРегламентноеЗадание – передать в качестве параметра непосредственно объект метаданных:
Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.ЗаписатьВЛог);
Важно! Создать регламентное задание можно только на основе существующего в метаданных объекта Регламентное задание. Указание других метаданных приведет к ошибке.
Создание и работа с фоновыми заданиями
При наличии в информационной базе регламентных заданий – предопределенных, или созданных программно – платформа будет на их основе создавать фоновые задания согласно расписанию. В большинстве случаев, достаточно корректной настройки регламентных заданий, чтобы фоновые задания своевременно и правильно отрабатывали.
Важно понимать, что фоновое задание – это объект встроенного языка, который предназначен для асинхронного выполнения прикладных задач. Фоновые задания нельзя запланировать при помощи языка 1С – только создать программно – и они тут же начнут выполняться.
Таким образом, можно сказать следующее: фоновые задания, созданные регламентным заданием выполняются по расписанию этого регламентного задания; а фоновые задания, созданные программно, выполняются немедленно в момент создания.
Выполнение фонового задания
Чтобы из языка 1С запустить фоновое задание, используется объект языка ФоновыеЗадания. Тип этого объекта – МенеджерФоновыхЗаданий. Для выполнения фонового задания служит метод Выполнить.
ФоновыеЗадания.Выполнить("РеглЗадания.ЗаписатьВЛог", , Строка(Новый УникальныйИдентификатор));
Выполнить в фоновом задании можно экспортную процедуру или функцию, которая должна быть размещена в общем неглобальном модуле.
Получение списка фоновых заданий
Фоновые задания могут выполняться очень длительное время, поэтому разработчику может понадобиться периодически опрашивать запущенные задания, чтобы узнать – какие уже выполнились, а какие все еще работают.
Для получения списка фоновых заданий используется метод ФоновыеЗадания.ПолучитьФоновыеЗадания(<Отбор>). Данный метод может получить как список всех фоновых заданий, если не указывать отбор, так и отфильтрованный список – например, только все активные фоновые задания, или фоновые задания с определенным методом, или же фоновые задания, созданные определенным регламентным заданием, и т.д.
В случае, если нам необходимо дождаться выполнения нескольких фоновых заданий, следует использовать метод ФоновыеЗадания.ОжидатьЗавершенияВыполнения(<Массив фоновых заданий>). Кроме того, у каждого фонового задания также есть аналогичный метод – который можно использовать, если мы хотим дождаться завершения одного конкретного фонового задания.
Регламентные задания в файловом варианте базы
При работе с файловой базой регламентные задания имеют ряд отличий от выполнения в клиент-серверном варианте.
Для выполнения регламентных заданий должен быть запущен клиентский сеанс.
- Регламентные задания в файловом варианте, вне зависимости от расписания обрабатываются раз в 60 секунд. Т.е. можно указать расписание 1 раз в 5 секунд, но все равно следующий запуск произойдет через 60 секунд. Второй пример: расписание настроено на 90 секунд. Но по факту фоновые задания будут выполнены с интервалом 120 секунд.
- Фоновые задания выполняются последовательно – т.е. в файловой базе одновременно не может работать два фоновых задания. Пока выполняется одно, остальные становятся в очередь на выполнение.
- Регламентные задания выполняются только одним клиентским приложением. При этом, если не указано специальных настроек, за выполнение регламентных заданий будет отвечать первый запущенный клиентский сеанс.
От сайта к сайту часто встречается информация, что для выполнения регламентных заданий в файловом варианте следует использовать метод ВыполнитьОбработкуЗаданий(). Данная информация устарела, и в последних версиях платформы 8.3. регламентные задания в файловом режиме настраиваются и работают практически так же как в клиент-серверной среде.
При работе в 1С встречается много рутинных операций которые должны запускаться или формироваться по расписанию выполняя то или иное действие, например: проведение документов или загрузка данных в 1С с сайта.
Недавно я разместил статью: Чтение данных с сайта в формате XML и загрузка в 1С пришло время это автоматизировать:
Регламентные и фоновые задания
Механизм заданий предназначен для выполнения какой-либо прикладной или функциональности по расписанию или асинхронно.
Механизм заданий решает следующие задачи:
- Возможность определения регламентных процедур на этапе конфигурирования системы;
- Выполнение заданных действий по расписанию;
- Выполнение вызова заданной процедуры или функции асинхронно, т.е. без ожидания ее завершения;
- Отслеживание хода выполнения определенного задания и получение его статуса завершения (значения, указывающего успешность или не успешность его выполнения);
- Получение списка текущих заданий;
- Возможность ожидания завершения одного или нескольких заданий;
- Управление заданиями (возможность отмены, блокировка выполнения и др.).
Механизм заданий состоит из следующих компонентов:
- Метаданных регламентных заданий;
- Регламентных заданий;
- Фоновых заданий;
- Планировщика заданий.
Фоновые задания & предназначены для выполнения прикладных задач асинхронно. Фоновые задания реализуются средствами встроенного языка.
Регламентные задания & предназначены для выполнения прикладных задач по расписанию. Регламентные задания хранятся в информационной базе и создаются на основе метаданных, определяемых в конфигурации. Метаданные регламентного задания содержат такую информацию как наименование, метод, использование и т.д.
Регламентное задание имеет расписание, которое определяет, в какие моменты времени нужно выполнять связанный с регламентным заданием метод. Расписание, как правило, задается в информационной базе, но может быть задано и на этапе конфигурирования (например, для предопределенных регламентных заданий).
Планировщик заданий используется для планирования выполнения регламентных заданий. Для каждого регламентного задания планировщик периодически проверяет, соответствует ли текущая дата и время расписанию регламентного задания. Если соответствует, планировщик назначает такое задание на выполнение. Для этого по данному регламентному заданию планировщик создает фоновое задание, которое и выполняет реальную обработку.
С описанием, думаю, хватит – приступим к реализации:
Создание регламентного задания
Имя метода – путь к процедуре, которая будет выполняться в фоновом задании по заданному расписанию. Процедура должна находиться в общем модуле. Рекомендуется не использовать типовые общие модули, а создать свой. Не забудьте, что фоновые задания исполняются на сервере!
Использование – признак использования регламентного задания.
Предопределенное – указывает, является ли регламентное задание предопределенным.
Если хотите что бы регламентное задание заработало сразу после помещения в БД, укажите признак Предопределенное. В противном случае вам необходимо будет использовать обработку “Консоль заданий” или вызывать запуск задания программно.
Количество повторов при аварийном завершении задания – сколько раз выполнен перезапуск фонового задания, если оно было выполнено с ошибкой.
Интервал повтора при аварийном завершении задания – с какой периодичностью будет выполнен перезапуск фонового задания, если оно было выполнено с ошибкой.
Настройка расписания
Расписание выполнения задания:
Каждый час, только один день | ПериодПовтораДней = 0, ПериодПовтораВТечениеДня = 3600 |
Каждый день один раз в день | ПериодПовтораДней = 1, ПериодПовтораВТечениеДня = 0 |
Один день, один раз | ПериодПовтораДней = 0 |
Через день один раз в день | ПериодПовтораДней = 2 |
Каждый час с 01.00 до 07.00 каждый день | ПериодПовтораДней = 1ПериодПовтораВТечениеДня = 3600ВремяНачала = 01.00
ВремяКонца = 07.00 |
Каждую субботу и воскресенье в 09.00 | ПериодПовтораДней = 1ДниНедели = 6, 7ВремяНачала = 09.00 |
Каждый день одну неделю, неделя пропуска | ПериодПовтораДней = 1ПериодНедель = 2 |
В 01.00 один раз | ВремяНачала = 01.00 |
Последнее число каждого месяца в 9:00. | ПериодПовтораДней = 1ДеньВМесяце = -1ВремяНачала = 09.00 |
Пятое число каждого месяца в 9:00 | ПериодПовтораДней = 1ДеньВМесяце = 5ВремяНачала = 09.00 |
Вторая среда каждого месяца в 9:00 | ПериодПовтораДней = 1ДеньНеделиВМесяце = 2ДниНедели = 3
ВремяНачала = 09.00 |
Особенности выполнения фоновых заданий файловом и клиент-серверном вариантах
Механизмы выполнения фоновых заданий в файловом и клиент-серверном вариантах различаются.
В файловом варианте необходимо создать выделенный клиентский процесс, который будет заниматься выполнением фоновых заданий. Для этого в клиентском процессе должна периодически вызываться функция глобального контекста ВыполнитьОбработкуЗаданий. Только один клиентский процесс на информационную базу должен выполнять обработку фоновых заданий (и, соответственно, вызывать данную функцию). Если клиентского процесса для обработки фоновых заданий не создано, то при программном доступе к механизму заданий будет выдана ошибка «Менеджер заданий не активен». Не рекомендуется клиентский процесс, выполняющий обработку фоновых заданий, использовать для других функций.
После того, как клиентский процесс, выполняющий обработку фоновых заданий, запущен, остальные клиентские процессы получают возможность программного доступа к механизму фоновых заданий, т.е. могут запускать и управлять фоновыми заданиями.
В клиент-серверном варианте для выполнения фоновых заданий используется планировщик заданий, который физически находится в менеджере кластера. Планировщик для всех поставленных в очередь на выполнение фоновых заданий получает наименее загруженный рабочий процесс и использует его для выполнения соответствующего фонового задания. Рабочий процесс выполняет задание и уведомляет планировщик о результатах выполнения.
В клиент-серверном варианте имеется возможность блокирования выполнения регламентных заданий. Блокирование выполнения регламентных заданий происходит в следующих случаях:
- На информационную базу установлена явная блокировка регламентных заданий. Блокировка может быть установлена через консоль кластера;
- На информационную базу установлена блокировка соединения. Блокировка может быть установлена через консоль кластера;
- Из встроенного языка вызван метод УстановитьМонопольныйРежим() с параметром Истина;
- В некоторых других случаях (например, при обновлении конфигурации базы данных).
Обработки запуска и просмотра регламентных заданий вы можете скачать здесь:
Для 8.2 Обычные формы: Konsol82.rar
Для 8.3 Управляемые формы: KonsolZadaniy83.rar