специализированные параметры фонового задания имеют слишком большой размер
Как передать в фоновое задание большую таблицу значений (12 млн записей)
такую таблицу проще затолкать в таблицу скуля и обработать там, если она на куски не рубится
Лучше придумать другой алгоритм «диспетчерзиации» задач между запущенными заданиями. Так, чтобы не требовалось гонять половину базы в оперативной памяти (а это и происходит при передаче параметров фонового задания).
>И не совсем понятно как объектные сущности в таблице значений разложить в таблице SQL много шаманства по моему будет
мы не в курсе накой черт тебе 12 лямов записей
>Как эта ТЗ формируется? Очень сложно?
либо тз с хз и в временный файл.
было не так давно в одной отраслевой упп.
модуль проведение документа.
внутри 2-го обход ТЧ и набивание ТЗ построчно.
теперь простая арифметика:
ТЗ = 10 000 000 строк
клиент «думает» до 2 Гб и падает
что делает клиент? звонит во франь, консультант франя заходит по rdp на сервак и (о чудо!) проводит документ. За 10 минут. Сервак 64-бит. А значит 3,5 Гб на клиента скребя ложкой по дну ему хватает.
какой вывод сделал франь?
купите 64-бит сервер 1с.
(38) При положении в ХЗ пойдет сериализация в XDTO + кодирование в base64, которое, я боюсь, выполнено через опу..
При извлечении из ХЗ пойдет обратный процесс.
(31) распараллеливается запись одного набора?
и в наборе 12 миллионов строк?
что-то я не очень понял.
странно что все пытаются придумать что делать с тз, вместо того, чтобы удостовериться в том, что в принципе выбрана правильная методика решения задачи.
(60) Все такие умные, что ППЦ.
А мы тут про расчет себестоимости.
(61)
Исследования методом «научного тыка» показали.
Для каждого типа делалась попытка:
(68) Масштабно, епта.
Результаты опубликуй.
ТЗ В XDTO есть? Нет? А если найду?!
(68) Дааа, ты чертовски прав..
1) Создал справочник с реквизитом ХЗ.
Простите за кодировку, было лениво морочиться.
К тому же, даже из вашей ссылки на вики:
> По замыслу разработчиков сначала должна быть описана
> структура данных, которая затем компилируется в классы,
Т.е. опять-таки нет речи о том, чтобы просто взять кусок оперативной памяти и зафигачить в файл (а потом просто прочитать из файла).
На основании объекта класса строится DTO-представление, которое уже и пишется файл.
Мегазадача. а если попробовать как-то получать из разных сеансов адрес ячеек в ОЗУ, занятых исходной таблицей (которую инициировал родительский сеанс)?
Можно создавать локальные и глобальные временные таблицы. Локальные временные таблицы видимы только во время текущего сеанса, а глобальные — во всех сеансах. Временные таблицы не подлежат секционированию.
Имени локальной временной таблицы должен предшествовать знак номера (#table_name), а имени глобальной временной таблицы — двойной знак номера (##table_name).
Инструкции SQL могут обращаться к временной таблице по заданному в инструкции CREATE TABLE значению аргумента table_name, например:
Длительные операции на сервере
Область применения: управляемое приложение.
1. При разработке конфигураций следует избегать длительных вызовов из клиентского кода в серверный. Все длительные серверные вызовы, которые могут выполняться более 8 секунд в обычных сценариях работы пользователя, следует выполнять асинхронно, с помощью фонового задания.
К таким операциям относятся: формирование отчета, групповая обработка объектов, загрузка или выгрузка данных в другое приложение, заполнение больших табличных частей и т.п.
В противном случае такие вызовы могут привести к потере работоспособности приложения или затруднению работы с ним:
2.1. Общий подход к асинхронному выполнению длительных серверных операций с помощью фонового задания:
а для прочих мест – выводится блокирующая форма ( РежимОткрытияОкна = БлокироватьОкноВладельца ), на которой размещена декорация с анимированной картинкой и кнопка «Отмена» :
2.2. Асинхронное формирование отчета требуется только для тех отчетов, которые
Поведение таких отчетов должно быть максимально похожим на поведение отчетов на базе СКД, а именно:
Пример выполнения функции в фоновом задании при использовании в конфигурации Библиотеки стандартных подсистем. В модуле менеджера объекта размещена функция, которая выполняет поиск настроек и возвращает их:
Функция ОпределитьНастройкиУчетнойЗаписи(АдресЭлектроннойПочты, Пароль) Экспорт
.
Возврат Настройки;
КонецФункции
В форме объекта выполняется вызов этой функции в фоновом задании в три этапа:
1) запуск фонового задания на сервере,
2) подключение обработчика завершения фонового задания на клиенте,
3) обработка результата выполнения фонового задания.
// 2. Подключение обработчика завершения фонового задания.
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
Оповещение = Новый ОписаниеОповещения(«ПриЗавершенииПоискаНастроек», ЭтотОбъект);
ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыОжидания);
КонецПроцедуры
// 3. Обработка результата выполнения фонового задания.
&НаКлиенте
Процедура ПриЗавершенииПоискаНастроек(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда // Пользователь отменил задание.
Возврат;
КонецЕсли;
Если Результат.Статус = «Ошибка» Тогда
ВызватьИсключение Результат.КраткоеПредставлениеОшибки;
КонецЕсли;
Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
УдалитьИзВременногоХранилища(Результат.АдресРезультата);
УстановитьНастройкиУчетнойЗаписи(Настройки);
Методическая рекомендация (полезный совет)
3.1. При каждом выполнении фонового задания его результат помещается во временное хранилище на время жизни формы:
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, ПараметрФоновогоЗадания);
Если длительная операция выполняется пользователем многократно, пока эта форма открыта, то временные хранилища накапливаются, что вызывает рост потребления памяти. Поэтому для уменьшения расхода оперативной памяти в большинстве случаев рекомендуется очищать временное хранилище сразу после получения результата фонового задания:
Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
УдалитьИзВременногоХранилища(Результат.АдресРезультата); // Данные во временном хранилище больше не требуются.
Если же результат фонового задания требуется сохранять на протяжении нескольких серверных вызовов, то необходимо передавать фиксированный адрес заранее инициализированного временного хранилища:
Возврат ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения,
«Справочники.УчетныеЗаписиЭлектроннойПочты.ОпределитьНастройкиУчетнойЗаписи»,
АдресЭлектроннойПочты, Пароль);
КонецФункции
4. Если в конфигурации реализуются алгоритмы, инициирующие запуск фоновых заданий или запись данных информационной базы без участия пользователя (например, регулярное обновление информации в открытой форме), то в них следует проверять, что в текущем сеансе не установлен монопольный режим. В противном случае, следует блокировать попытки выполнения таких действий. Например:
Если МонопольныйРежим() Тогда
Возврат;
КонецЕсли;
5. В некоторых случаях возникает необходимость в выполнении длительных операций, требующих установки монопольного режима доступа к информационной базе. Например:
При этом необходимо сначала устанавливать монопольный режим, а затем выполнять запуск фонового задания, которое реализует саму длительную операцию. В этом случае фоновым заданием будет унаследован монопольный режим, ранее установленный из пользовательского сеанса (см. документацию к платформе).
На время выполнения этого фонового задания следует блокировать весь интерфейс приложения, открывая форму ожидания завершения операции в режиме РежимОткрытияОкна = БлокироватьВесьИнтерфейс. Блокировать интерфейс приложения требуется потому, что на время выполнения задания полноценная работа пользователя с приложением уже невозможна:
* Примечание: ошибки записи также возникают в тех случаях, когда объекты записываются программно, например, из обработчиков ожидания. В них также следует проверять монопольный режим согласно п.5.
Ошибка перехода конфигурации ЗУП КОРП с 3.1.18.83 на 3.1.18.119
После обновления конфигурацию 3.1.18.83 на 3.1.18.119, возникает ошибка дополнительных фоновых заданий:
Процедура «Справочники.ОснованияУвольнения.ОбновитьОснованияВАрхиве» обработки данных завершилась с ошибкой:
Слишком много фактических параметров
Технические подробности:
Ошибка выполнения фонового задания ДлительныеОперации.ВыполнитьСКонтекстомКлиента с идентификатором 18fe36e0-d6d5-4d32-85cc-293124e807ea по причине
Слишком много фактических параметров
<(1)>:Справочники.ОснованияУвольнения.ОбновитьОснованияВАрхиве(Параметры[0])
<ОбщийМодуль.ОбщегоНазначения.Модуль(5262)>: Выполнить ИмяМетода + «(» + ПараметрыСтрока + «)»;
<ОбщийМодуль.ОбновлениеИнформационнойБазыСлужебный.Модуль(4011)>: ОбщегоНазначения.ВыполнитьМетодКонфигурации(КонтекстОбработчика.ИмяОбработчика, ПараметрыВызова);
<(1)>:ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенныйОбработчик(Параметры[0],Параметры[1])
<ОбщийМодуль.ОбщегоНазначения.Модуль(5262)>: Выполнить ИмяМетода + «(» + ПараметрыСтрока + «)»;
<ОбщийМодуль.ДлительныеОперации.Модуль(1067)>: ОбщегоНазначения.ВыполнитьМетодКонфигурации(ИмяПроцедуры, ПараметрыВызова);
<ОбщийМодуль.ДлительныеОперации.Модуль(1057)>: ВызватьПроцедуру(ВсеПараметры.ИмяПроцедуры, ВсеПараметры.ПараметрыПро
Фоновые задания: быстро получить большие данные в 1С
Вводная
Представим, что нужно периодически запрашивать какой-то большой объем данных из внешней системы, но повлиять на скорость ответа внешнего сервиса/системы мы не можем, а очень хочется получать данные быстро. При этом открыть несколько параллельных сеансов внешняя система не запрещает. Тогда на помощь приходят они ФоновыеЗадания 1С в серверной базе (в файловой базе выигрыша в скорости не происходит).
Увеличение скорости происходит не линейно и максимально мне удавалось достичь ускорения за счет параллельности максимум в 3-5 раз от скорости в 1 сеансе. Это происходит из-за того, что тратятся ресурсы и время на создание параллельных сеансов, а потом на ожидание и сборку результатов.
Чтобы достичь максимального эффекта для конкретной задачи приходится опытным путем в песочнице определять:
В 1С теоретически можно создать сколь угодно много фоновых заданий, нО. внешняя система либо может не выдержать такой нагрузки, либо просто забанит нас. Потому рекомендую программно ставить ограничение в 1С не более 10-30 одновременных потоков.
Алгоритм действий:
Объекты метаданных которые понадобятся для решения:
В общем модуле нам достаточно 1 экспортной процедуры, куда передается на вход сформированный ранее в обработке текст запроса и идентификатор фонового задания для записи промежуточного результата работы процедуры в РегистрСведений с этим же идентификатором.
Вспомогательные процедуры/функции и другие выполняющие собственно саму работу процедуры для настоящей статьи не существенны и могут меняться в зависимости от задачи. Имеются в приложенном файле конфигурации.
В обработке запуска фоновых заданий получаем из внешней системы или придумываем свой уникальный идентификатор, по которому будем бить задачи на порции. В примере для ADS берем выборку ключевого поля из нужной таблицы и потом разбиваем полученный результат на структуру, содержащую массивы порционных ключей таблицы.
Если установили ограничение на максимальное количество одновременных фоновых заданий, то в цикле запуска фоновых заданий останавливаемся при достижении лимита, ждем завершения ранее созданных заданий, собираем промежуточные результаты и только потом двигаемся дальше.
Вызов фоновых заданий выполняется в цикле через метод ФоновыеЗадания.Выполнить(), который выполнит сделанную ранее в общем модуле экспортную процедуру. Фоновому заданию передается: ИмяОбщегоМодуля.ИмяЭкспортнойПроцедуры, массив параметров и идентификатор фонового задания, по которому потом будем собирать данные из РегистраСведений.
На выходе получаем результирующие данные из параллельных фоновых заданий.
В заключение
Все примеры и листинги сделаны как эмуляция заполнения массивов и таблиц значений, а если прописать настоящий адрес, ключевое поле и имя таблицы и выключить эмуляцию, то работает с Advantage Database Server (далее – ADS), СУБД понимающей стандартный язык запросов T-SQL через Com объекты ADODB. Алгоритм можно использовать в любых похожих ситуациях с любыми СУБД, внешними службами, когда требуется ускорить/распарралелить вычисления.
В прилагаемом к статье файле конфигурация с 3 объектами для работы с ФоновымиЗаданиями 1С, включая все необходимые вспомогательные и служебные процедуры, функции, чтобы не зависеть от БСП и типа, версии конфигурации. Легко добавить в любую конфигурацию, если есть возможность изменения или как расширение и затем быстро подкорректировать под свою задачу. Формы Регистра и Обработки управляемые. Версия Платформы требуется не ниже 8.3.13, конфигурация любая.
Фоновые задания в 1С 8.3
Фоновые задания
Иногда требуется выполнить какую-нибудь длительную операцию без блокирования интерфейса. То есть пользователь нажал кнопку, запустилась какая-нибудь длительная процедура, а в этом время пользователь может делать что-нибудь другое в программе. Для этого можно использовать механизм фоновых заданий.
Фоновые задания запускаются асинхронно (без ожидания завершения), в отдельном потоке. Фоновые задания можно запустить только на сервере. Для примера, представим что есть некий список электронных адресов, на который нужно выполнить рассылку по электронной почте. В списке может быть много адресов, да и отправка одного письма выполняется какое-то время. Поэтому хотелось бы запустить рассылку и продолжить дальше работать с программой.
Чтобы запустить фоновое задание используется метод Выполнить менеджера фоновых заданий. Первым параметром передается имя общего модуля и имя метода. Указанный метод должен находиться в общем модуле и быть экспортным.
В результате будет запущено фоновое задание, которое выполнит метод ВыполнитьРассылку из общего модуля МодульФоновыхЗаданий. Во время выполнения фонового задания интерфейс пользователя не будет заблокирован.
Если сейчас трижды запустить одно фоновое задание, то оно будет запущено три раза и три раза выполнит одно и то же действие. Чтобы избежать повторного запуска фонового задания, если оно уже было запущено можно использовать Ключ фонового задания. Ключ передается третьим параметром в метод Выполнить:
В результате при первом выполнении данного кода будет запущено фоновое задание с ключом «Рассылка». Если не дождавшись выполнения текущего фонового задания попробовать запустить его еще раз, то будет выброшено исключение «Задание с таким значением ключа уже выполняется». Если указать другое значение ключа, то оба фоновых задания будут выполняться одновременно.
Если у фоновых заданий с одним значением ключа не совпадают методы для выполнения, то такие задания могут быть запущены одновременно.
Стоит отметить, что в качестве метода для фонового задания можно использовать как процедуру, так и функцию. Возвращаемый результат функции будет проигнорирован. В качестве метода фонового задания нельзя использовать методы глобальных общих модулей.
Параметры фонового задания
При запуске фонового задания можно передать параметры в метод общего модуля. Например, добавим в процедуру ВыполнитьРассылку два параметра:
При запуске фонового задания вторым параметром нужно перадать массив параметров. Первый элемент массива будет передан в первый параметр, второй — во второй и т.д.
Если количество параметров не будет совпадать, то фоновое задание не будет выполнено.
Фоновые задания в файловом и клиент-серверном варианте
Механизм выполнения фоновых заданий отличается в файловом и клиент-серверном варианте.
В файловом варианте фоновые задания выполняются на том клиентском приложении, которое его запустило. Одновременно может выполняться только одно фоновое задание, остальные фоновые задания встают в очередь.
В клиент-серверном варианте фоновые задания выполняются планировщиком заданий, который находится в менеджере кластера. Планировщик заданий подбирает наименее загруженный рабочий процесс сервера 1С и выполняет фоновое задание на нем.
И в файловом и клиент-серверном варианте фоновое задание это отдельный системный сеанс, который выполняется от имени того пользователя, кто создал задание.
Фоновое задание с ожиданием результата
Если требуется дождаться результата выполнения фонового задания, то можно воспользоваться тем, что метод Выполнить возвращает объект Фоновое задание. А у этого объекта есть метод ОжидатьЗавершенияВыполнения, который остановит поток выполнения, пока не изменится состояние фонового задания. Фоновое задание может быть в четырех состояниях:
После изменения состояния фонового задания метод ОжидатьЗавершенияВыполнения вернет обновленное фоновое задание, у которого можно анализировать свойство Состояние, чтобы узнать результат выполнения:
Метод Выполнить вернул фоновое задание, состояние которого было равно Активно. Состояние автоматически не обновляется. Для проверки изменения состояния фонового задания нужно заново получить фоновое задание. В данном примере оно было получено методом ОжидатьЗавершенияВыполнения.
Пауза через фоновое задание
В метод ОжидатьЗавершенияВыполнения параметром можно передать количество секунд. Выполнение кода продолжится или по истечении этого времени или сразу после изменения состояния фонового задания. Можно воспользоваться данным методом для возможности оставить выполнение кода на указанное количество секунд. В общий модуль добавим следующую процедуру:
Параметром принимаем количество секунд для паузы, затем определяем чей это сеанс. Если клиентский, то запускаем фоновое задание и ждем его завершения. Если это сеанс фонового задания, то просто ждем его завершения.
Вызов паузы на 5 секунд:
Преимущество такого метода в том, что на время паузы не загружается процессор.
Оповещение о выполнении фонового задания
Иногда требуется не просто запустить выполнение фонового задания, а оповестить пользователя о результатах выполнения. Для этого можно использовать следующий алгоритм действий:
Здесь был использован метод ПодключитьОбработчикОжидания, который вызывает процедуру, указанную в первом параметре через время, указанное во втором параметре. Затем вызов процедуры был отменен через метод ОтключитьОбработчикОжидания.
Отмена выполнения фонового задания
Для отмены фонового задания можно использовать метод Отменить самого фонового задания:
Сообщения из фонового задания
Фоновое задание выполняется на сервере, поэтому если в нем использовать сообщения пользователю, то их никто не увидит. Однако у фонового задания есть метод ПолучитьСообщенияПользователю, который позволяет получить все сообщения из фонового задания. Для примера добавим в общий модуль следующую процедуру:
Выполним ее через фонового задание с получением всех сообщений и выведем полученные сообщения на экран:
Через сообщения можно организовать получение прогресса выполнения фонового задания. Добавим в общий модуль следующие процедуры:
И запустим фоновое задание на выполнение, с периодическим получением сообщений:
В результате в процессе выполнения фонового задания можно будет увидеть окно состояния с прогрессом выполнения:
Многопоточность через фоновые задания
С помощью фоновых заданий можно выполнить какую-то обработку в несколько потоков. Например, нужно во всем справочнике товаров увеличить цену на 10%. Можно разбить все товары на несколько частей и каждую часть обработать в отдельном потоке:
Здесь мы использовали метод ОжидатьЗавершения, но уже не у самого фонового задания, а у менеджера фоновых заданий. Параметром передали массив тех фоновых заданий, завершение которых нужно дождаться. У менеджера фоновых заданий тоже есть метод ОжидатьЗавершенияВыполнения, в который помимо массива заданий можно передать таймаут, аналогично одноименному методу у фонового задания. Даже если в методе ОжидатьЗавершенияВыполнения не указывать таймаут, то он в любом случае вернет массив всех обновленных фоновых заданий, после изменения статуса хотя бы у одного задания. Так как нам нужно дождаться завершения всех заданий, то был использован метод ОжидатьЗавершения.
Стоит отметить, что в одном фоновом задании можно запустить другое фоновое задание. То есть можно было запустить одно фоновое задание, в нем распараллелить выполнение на четыре фоновых задания, дождаться их выполнения и оповестить пользователя о завершении.
В силу ограничений выполнения фоновых заданий в файловом варианте многопоточную обработку данных можно реализовать только в клиент-серверном варианте.
Получить фоновые задания
Метод ПолучитьФоновыеЗадания позволяет получить список всех фоновых заданий, сохраненных в базе данных. Выполненные фоновые задания хранятся в течении суток, но не более 1000 заданий. Соответственно метод ПолучитьФоновыеЗадания вернет как текущие фоновые задания (выполняются в данный момент), так и завершившиеся в течении суток задания.