Представление:
Дополнительно к Анонсу хочу написать следующее: Данная статья описывает принципиально новый, удобный, практичный и отказоустойчивый способ управления Фоновыми заданиями. Обработка, которая представлена в результате пока в этой статье в сочетании с Демо-версией компоненты - была проверена на различных краш-тестах, и крутилась сутками загоняя систему под исчерпания лимита памяти. Количество объектов, которые можно создать, а также количество свойств в каждом объекте, размер данных для обмена - ограничены только ресурсами компьютера. Тестировал от 300-500 тыс. свойств на x32 системе до свыше 2-3 миллионов свойств на x64. Тестирование проводилось на разных платформах в вариантах Native на 8.2 (19 релиз) и 8.3 (релизы от 8.3.3 до 8.3.22) в системе Windows x86 и x64. Также проводился анализ утечек памяти. Добавилось: в связи с расширением функционала компоненты с возможностью её использования на серверах старых верcий 8.0 и 8.1 через интерфейс IDispatch (COMОбъект), разработан механизм управления Фоновыми заданиями на серверах в указанных версиях 1С, с некоторыми потерями производительности, но без альтернатив других видов коммуникации.
Введение:
Прежде чем описывать способы управления Фоновым заданием, проведу небольшой Ликбез. Что такое Фоновое задание для системы, как оно реализуется, почему мы просто так не можем взаимодействовать с Фоновым заданием.
Когда мы запускаем на выполнение Фоновое задание, 1С на сервере создает на текущем серверном процессе сеанс "Фоновое задание", каждый сеанс кроме того что он имеет свой набор прав и привилегий, указание под каким пользователем выполняется, параметры сеанса, он также в Приоритетном (это важно) порядке запускается на том же самом процессе, который дал команду это задание запустить. Т.е. Если у Вас активно 10 серверных процессов и нет ограничений по количеству соединений на процесс,
ограничений по памяти, то пусть у Вас хоть на этом процессе висит 10 соединений, а на остальных ничего, в любом случае запуск будет на текущем процессе. В виде исключения, когда лимиты исчерпаны или явное отключение (сделать неактивным) этого серверного процесса, то Фон будет выполняться на текущем процессе.
На примере, мы вначале ограничили количество сеансов на процесс 1, затем запустили 4 приложения 1С, потом сняли ограничение и теперь каждый сеанс запускает Фон в своем процессе. Это правило работает на 8.3 последних релизов. На версиях 8.2, к сожалению это не срабатывает. Однако, если Ваша организация использует всего один серверный процесс на 8.2, то Вы вполне можете воспользоваться моим решением, которое рассматривается в этой статье. Что касается версий 8.0 и 8.1, то в версии 8.0 всегда только один серверный процесс, который может даже не быть службой, а в версии 8.1 редко когда используется более 1-го процесса, а если и приходится, то это все настраивается вручную в консоли сервера и там можно будет задать свойство "Производительность", которое будет сильно отличаться от остальных (например оставить по умолчанию значение 1000, а в остальных процессах сделать 10-100. Тогда в 8.1. мы с большей долей вероятности запустим Фон на этом же самом серверном процессе.
Для тех, кто умеет программировать на других языках высокого уровня, таких как C++, C#, Java будет интересно узнать, что каждое Фоновое задание запускается как отдельный Поток в системе называемый Thread. Соответственно отсюда все проблемы с синхронизацией доступа к общим данным, и соответственно нет возможности передать через общие переменные какие то данные в вызываемый поток и из него. Также это может вызывать проблемы при обменах легальным способом, например через Хранилища настроек, которое мы рассмотрим позже.
Существует 2 способа запускать Фоновое задание:
- Через Регламентные задания - мы это не рассматриваем.
- Явно через менеджер Фоновых заданий.
Здесь, мы можем через параметр передать Заданию какие-то первоначальные данные и ждать пока это задание вернет нам результат. Причем есть легальные способы получить значения от Фона, например через объекты СообщениеПользователю (это всем известно), через Хранилище настроек (будет рассматриваться), через журнал регистрации, через Параметры Сеанса (если под текущим пользователем) и наконец через данные в регистрах или справочники.
У каждого из способов есть либо ограничения, либо есть большие затраты ресурсов, иногда возникают проблемы с нехваткой памяти, если например, при реализации движения Индикатора мы используем Сообщения, то в случае если Клиент не очищает буфер сообщений, то память переполняется и процесс может вылететь и потеряются важные данные.
Теперь о главном.
Идея сделать упрощенный обмен с Фоновыми заданиями пришла мне давно, вначале конечно искал легальные способы. Ждал когда появится что-то подобное структуре или объекту, через который я могу обмениваться с параллельными потоками, и в частности с Фонами. Потом конечно в перспективе и с процессами, а затем и с компьютерами в рамках одной сети. Для начала, мне для обмена с Фоном и передачи команд нужна была как минимум структура, повторяющая свойства элемента формы "Индикатор", так чтобы я мог нужную мне обработку с Индикатором запускать как в Обычном, так и в Фоне если я открываю её в УФ. Далее, остается проблема с Сообщениями. Не хочется терять сообщения, некоторые из которых могут быть ошибками. Практика показала, что история с передачей сообщений от Фона клиенту - нестабильна. Некоторые сообщения исчезают. Я позже покажу статистику по этому вопросу для варианта обмена через Хранилище настроек. Так вот, почему бы не передавать Сообщения также через объект, структуру, но которая бы хранилась в памяти. Это не грузит процесс ресурсами, т.к. с помощью итерации и удаления уже обработанных сообщений, можно сразу же разгружать этот массив. Итак мне было необходимо для реализации этой идеи:
- Структура или объект - эмулирующий структуру, которая была бы доступна одновременно из двух и более разных потоков (в идеале, процессов) в режиме реального времени.
- Все операции со структурой, хотя бы в рамках обмена с потоками, выполнялись бы со временем выполнения, которое было бы соизмеримо со временем выполнения обычной структуры, не намного превышало бы. Забегая вперед скажу, что для старых релизов версий 1С 8.3, и версий 8.2, а также, в том числе в режиме COM, для версий 7.7, 8.0, 8.1 она даже в некоторых случаях была быстрее.
- Набор свойств структуры был динамическим, а при превышении определенного количества свойств, был бы отсортирован по ключам. Это экономит время на операции и удобнее для работы и отладки.
- Поддержка итерации - нужна для работы в частности с сообщениями как с массивом.
- Поддержка процедуры ЗаполнитьЗначенияСвойств - ускоряет копирование данных, особенно при значительных количествах свойств.
- Все операции по чтению и записи свойств этой структуры должны быть безопасны с точки зрения поддержки параллелизма (потоков), и отказоустойчивы. По отказоустойчивости очень строгие требования, должна структура, например в режиме итерации, готова к тому что параллельный поток тоже эту же структуру перебирает и может как записывать, так и удалять записи и даже по текущему ключу. Процесс не должен вылетать с необрабатываемым исключением, а максимум должна возвращаться ошибка в формате, который воспринимается 1С и отлавливается ею. В частности в указанном примере: мы стоим на выборке, её значение удалили в параллельном потоке, читаем ключ - он равен Null, Значение - тоже Null.
- Должны быть минимизированы отказы и исключения на стороне структуры, в том числе в результате блокировки операций несколькими параллельными потоками, т.е. не должна быть разовая попытка и сразу отказ.
- Должна быть компонента работающая на сервере, в случае с младшими версиями 1С 8.1-, где не поддерживаются компоненты, должен быть COMОбъект, работающий через интерфейс IDispatch.
- Когда будет реализован механизм обмена между процессами или компьютерами (через SQL), тогда можно будет обмениваться и между разнородными информационными базами.
Итак, я пришел к идее написать компоненту Аддон (ExchangeStruc).
Концепция варианта взаимодействия с Фоном с помощью Структуры Обмена и краткое описание работы компоненты.
К текущей статье прилагается демонстрационная обработка тестирования новой компоненты, которая тестирует практически все основные операции со Структурой Обмена в режиме, который мы задаем, помимо этого используя эту компоненту при выполнении теста в Фоновом задании мы реализуем тот самый механизм обмена с Фоном, поэтому я на примере этой схемы работы и опишу концепцию работы Структуры Обмена. Для начала приведу схему взаимодействия клиента с Фоном через этот Аддон.
По схеме видно, что в какой-то момент времени, клиентское приложение, через обращение к своему сеансу на сервере, находит или создает объект (Аддон) Структуры Обмена с помощью метода ПолучитьСтруктуру(GetStructure). По названию структуры (ключу), например "УправлениеФон", Аддон находит в Пуле памяти процесса, массиве "Именованных структур", необходимую ему структуру и позиционируется на её, входит в Режим 1 (Структура). Далее работаем с Аддоном в этом режиме как со структурой 1С. В этом режиме поддерживаются функции и процедуры, аналогичные структурам 1С, такие как Свойство(Property), Вставить(Insert), Удалить(Delete), и ряд дополнительных методов, пока не буду их все описывать, это будет сделано в отдельной статье. В отличии от 1С, Аддон поддерживает Итерации (перебор) структур другим способом: вместо операторов Для каждого использует функции Выбрать(Select) - начало выборки, вход в режим 2 (Итерация), Следующий(Next) - переход к следующей ключевой паре , Сбросить(Reset) - в режиме Выборки - перепозиционироваться на начало Выборки, и Владелец() - выход из режима 2 (Итерации) и вернуться в режим 1 структура. Всего Аддон поддерживает 3 режима, которые содержат в зависимости от режима тот или другой набор свойств. Режим 0 - корневой, в котором мы можем установить некоторые свойства самого Аддона, указать какой тип подключения (Тип SQL сервера) использовать, пока используем тип "РазделяемаяПамять (SharedMemory)" - по умолчанию. Режим 1 (Структура) с динамическим набором свойств и Режим 2 (Итерация) со свойствами Ключ и Значение.
В другой публикации будет подробно описан функционал самой компоненты, здесь нас интересует последовательность Взаимодействия с Фоном. Продолжу описывать конкретно её:
Клиент: Клиент взаимодействует с Фоном через сеанс Сервера. В сеансе на Сервере, если Аддон только что создан, то он должен выполнить подключение (тип подключения стоит по умолчанию "Разделяемая память") методом Подключить(Connect), затем установкой глобального свойства всех Аддонов в процессе Синхронизация для возможности обмена структурами Аддона с другими Потоками (в частности с Фоном). Сеанс на Сервере позиционируется на Структуре Управления как описано ранее по ключу. Затем сеанс получает заполненные Фоном данные из структуры Аддона и при необходимости передает команды или данные в Фон через эту структуру. Отдельным вызовом сеанс на Сервере также проделывает со Структурой Сообщения, только он при считывании сообщений, затем удаляет их из Аддона.
Фон. Фон тем временем продолжает свою работу. Предварительно, вначале своей работы, создает 2 дополнительных объекта Аддона, чтобы не переключаться между ними: Структуру Управления и Структуру Сообщений, позиционируясь на них чтобы сэкономить время. Выполняя свою работу устанавливает некоторые свойства в Структуре и периодически мониторит Структуру управления на наличие команд от Клиента. Также когда необходимо передать Сообщение пользователю, Фон через Структуру Сообщений вставляет новое значение. Как мы видим, Фон минимизирует свою работу с Аддоном, читая ряд свойств одного объекта и записывая по необходимости новые значения в один и вставляя новое значение в другой объект. Для Фона вся работа по Взаимодействию выглядит прозрачно как с обычной структурой 1С.
Кеширование аддона - отдельный Фоновый процесс (Робот), который ничего не делает, но может быть использован для гарантии того что Фон получит на входе все инициализированные свойства в Структуре управления и при завершении работы, Клиент сможет получить результат, оставшиеся Сообщения и последние значения, переданные Фоном. Он должен быть начат до выполнения основного задания Фона и может быть выгружен, когда ему Клиент передаст определенную команду, например установкой свойства Структуры Управления "ВПроцессе" в Ложь.
Демонстрация работы компоненты в разных режимах запуска 1С для вариантов через Структуру Обмена и Хранилища настроек.
Для экономии времени, я записывал Видео периодически выключая запись, но все же это длительный процесс. Вы можете через ускоренное произведение сократить время просмотра.
- Демонстрируется процесс взаимодействия через Аддон. Мы запускаем 5 программ 1С в режиме Обычного приложения, включаем на них режим Автообновление. Заданный интервал обновления 0,1 секунды указывает, что теоретически может быть интервал обращения к Фону до 20 мс (до 50 вызовов в секунду). Затем настраиваем на одной программе параметры тестирования 1 миллион свойств (1000 объектов x 1000 свойств) и запускаем тест в Фоне. Далее Вы можете наблюдать как проходит изменение содержимого окон и шкалы Прогресса во всех окнах, а также поступление Сообщений в разные окна.
- Как видно в конце Видео мы получаем все 16 Сообщений от Фона, хотя и в разных окнах. Это означает что заданный нами алгоритм по передачи Сообщений работает без сбоев. Время работы Фона около 30 мин. По данных Фона, время потраченное непосредственно на тестирование: (21:45.343+7:7.422) = 28:52.765, отсюда, время на Взаимодействие между процессами получается примерно 1:08 мин
- Демонстрируется процесс взаимодействия через Хранилище настроек. Все настройки тестирования взяты из Видео 1. Отличие в том, что мы в каждом Приложении переустановили константу "Управление фоном" в значение Хранилище настроек, чтобы Параметры сеанса тоже переустановились. Также отключен в Фоне режим Синхронизации, что должно ускорить работу Фона, в части тестирования структур Аддона
- Демонстрируется процесс взаимодействия через Аддон. Также как и в Видео 1 Мы запускаем 5 программ 1С в режиме Обычного приложения, включаем на них режим Автообновление. Меняем параметры тестирования, остается 1 миллион свойств, но иначе собранный (10 объектов x 100 000 свойств) и запускаем тест в Фоне. Наблюдаем изменение содержимого окон и шкалы Прогресса во всех окнах, а также поступление Сообщений в разные окна.
- По прежнему в конце Видео мы получаем все 16 Сообщений от Фона. Взаимодействие происходит как надо. Время работы Фона 30:17 мин. По данных Фона, время потраченное непосредственно на тестирование: (20:39.357+7:48.725) = 28:28.082, отсюда, время на Взаимодействие между процессами получается примерно 1:51 мин.
- Демонстрируется процесс взаимодействия через Хранилище настроек. Все настройки тестирования с теми же изменениями что и на Видео 3. Также как и во 2 Видео, переустановили константу "Управление фоном" в значение "Хранилище настроек" и отключен в Фоне режим Синхронизации.
- Демонстрируется процесс взаимодействия через Аддон. Мы запускаем 5 окон обработки одного сеанса 1С в режиме Тонкий клиент, включаем на них режим Автообновление. Интервал обновления тот же 0,1 секунды - интервал обращения к Фону до 20 мс (до 50 вызовов в секунду). Параметры тестирования: 1 миллион свойств (1000 объектов x 1000 свойств), остальные те же. Сообщения, несмотря на то что могут забираться разными окнами, будут закрепляться за активным окном. Состояние для всех 5 окон выводится в отдельном окне.
- В отличие от предыдущих тестов этот отработал медленнее в 1,7 раз из за того что тестирование выполнялось на одном и том же компьютере где сервер находится, а все операции по обновлению содержимого окон, если они часто происходят нагружают как сервер. По прежнему в конце Видео мы получаем все 16 Сообщений от Фона. Взаимодействие происходит как надо. Время работы Фона 52 мин. По данных Фона, время потраченное непосредственно на тестирование: (31:22.418+15:45.388) = 47:07.808, отсюда, время на Взаимодействие между процессами получается примерно 4:52 мин.
- Демонстрируется процесс Обратного взаимодействия через Аддон. Мы запускаем 3 приложения 1С в разных режимах: Обычное Приложение, УФ:Толстый клиент, УФ:Тонкий клиент, включаем на них режим Автообновление. Параметры тестирования не имеют значения, нам требуется показать как реагирует Фон на передачу команд от Клиента через Аддон.
- Поочередно мы запускаем Фон в каждом из приложений, в другом приложении мы нажимаем кнопку Прервать. Видим что 1С довольно шустро реагирует и прекращает выполнение Фона и все окна обновляются корректно.
- Новое: Демонстрация коммуникации с Фоном на младших версиях 1С: 8.1 и 8.0 - 2 приложения с использованием Аддона как COMОбъект на указанных серверах.
Вначале демонстрируется запуск и прерывание, затем завершение работы Фонового задания в версии 8.1 на двух окнах (приложениях.).
Затем та же ситуация в режиме эмуляции Фона на версиях 8.0. Стоит отметить, что на данной версии нет объекта Фоновое задание, и его приходится запускать через автономное параллельное приложение, которое скрыто и оно тоже обращается к серверу.
Пошаговое описание Взаимодействия с Фоном на примере работы Демонстрационной версии обработки Тестирования компоненты.
По шагам весь процесс взаимодействия с Фоном в Демо-версии выглядит так:
- Запускаем Тестирование в режиме Фона:
- Отрываем форму внешней обработки, которая прилагается в Демо-версии. База данных с некоторыми общими модулями должна быть предварительно установлена на сервере 1С под Windows x32/x64, в Демо-версии прилагается конфигурация и тестовая база для загрузки. Режим запуска клиента не имеет значения.
- Подключаем компоненту и нажимаем кнопку Тестирование.
- Устанавливаем параметры тестирования как на скриншоте, кликом на строку каждого параметра, мы можем его изменить. Следует отметить, что если Вы самостоятельно будете тестировать на Демо-версии обработки, то не ставьте больше 100 объектов и более 1000 свойств на объект, т.к. у Демо-версии стоит ограничение по времени выполнения, потом она перестает устанавливать новые свойства.
- Устанавливаем время Автообновления в 1 (0,1 сек.) и затем ставим галку "Автообновление" непосредственно перед нажатием кнопки Выполнить. Затем кнопку Выполнить.
- Перед запуском рабочего Фона, Клиентское приложение (Клиент) проверяет, запущен ли рабочий Фон.
- Если не запущен, то в случае работы в режиме Обычного приложения, запускается Фоновое задание поддержки Аддона (Робот), который будет просто хранить объект Аддона со Структурой Управления и Структурой сообщений в памяти до запуска рабочего Фона, и после завершения работы Фона, Робот будет хранить все последние значения этого процесса и результат его выполнения, а также все Сообщения. Заодно передаем Роботу структуру со значениями для инициализации объекта Аддона структуры управления Фоном, в том числе название Структуры Управления через свойство "Ключ".
Следует отметить, что сеанс на сервере 1С не умеет хранить локальные переменные, поэтому если мы создаем объект Аддона для доступа к Структуре Обмена, то при следующем запуске он будет уничтожен. В 1С версий 8.2 и 8.3 есть способ сохранить объект Аддона в сеансе с помощью функции ПоместитьВоВременноеХранилище. Пример:
// При повторном входе в сеанс Сервера, проверяем есть ли Аддон по переданному адресу
Аддон=ПолучитьИзВременногоХранилища(АдресАддона);
// Для 8.3 Аддон может быть кеширован через структуру
ЕстьАддон=?(ТипЗнч(Аддон)=Тип("Структура"),Аддон.Свойство("Аддон",Аддон) И Аддон<>Неопределено,Ложь);
Если Не ЕстьАддон Тогда
... // Создаем объект компоненты, при необходимости загружаем её
КонецЕсли;
... // Выполняем работы с компонентой
// Перед выходом если необходимо сохраним Объект в кеше Сеанса
Если Не ЕстьАддон Тогда
// Для версий 8.2. УникальныйИдентификатор передается - для вызовов из УФ
АдресАддона=ПоместитьВоВременноеХранилище(Аддон,УникальныйИдентификатор); // Помещаем объект компоненты в память сеанса сервера
// Для версий 8.3 УникальныйИдентификатор передается - для вызовов из УФ
АдресАддона=ПоместитьВоВременноеХранилище(Новый Структура("Аддон",Аддон),УникальныйИдентификатор); // Помещаем объект компоненты в память сеанса сервера
КонецЕсли;
Возврат АдресАддона; // Либо так, либо через переменную
Здесь, как заявлено в документации 1С, переменная может быть уничтожена при следующем запуске сеанса на сервере, если мы передаем УникальныйИдентификатор формы (УИ) она хранится пока открыта форма (УФ). По факту, объект Аддона живет даже в режиме Обычного приложения и УФ - ещё минут 20, даже если мы не передавали УИ. Но если у пользователя случайна закрылась форма, или он решил выключить компьютер, то чтобы у нас сохранилась последняя информация от рабочего Фона, то наверно стоит хотя бы одного Робота на процесс иметь запущенным.
- Запускается рабочий Фон с параметрами тестирования, которые мы предварительно установили. Опишу то что нас интересует в этом процессе для реализации обмена с Фоном. Фон выполняет следующее:
- Рабочий Фон создает объект обработки по указанному в параметрах пути. Находит Структуру Управления Фоном по переданному имени и по этому имени с суффиксом "MSG" создает структуру сообщений. Например, Структура Управления называется "ПараметрыФормы", тогда Структура Сообщений будет называться "ПараметрыФормыMSG".
- Запускает в режиме Сервер функцию из модуля обработки для выполнения переданных в параметрах этапов тестирования.
- Максимальное кол-во этапов 16
- Каждый из них сопровождается сообщением пользователю через Структуру сообщений. Обработка просто вставляет новое свойство с номером сообщения в эту структуру. Номер сообщения увеличивается с каждой операцией. Здесь мы можем проверить как работает передача сообщений через наш механизм. В формы должно прийти 16 сообщений, если выбраны все виды теста. Я в ключе свойства сообщения реализовал хранение значения статуса сообщения через символ "_", исключая пробел, например: "Msg000001_Внимание", "Msg000002_Обычное" и т.д. Это позволяет и отсортировывать корректно эти сообщения по мере их поступления, контролировать их целостность, и правильно выводить иконку (статус).
- В цикле каждого этапа, устанавливается (сдвигается индикатор) исходя из своего диапазона минимального и максимального значения, который просчитывается по данным структуры Управления, значение индикатора передается в структуру управления. В идеале было бы хорошо иметь 2 индикатора, один для этапа, второй для всего процесса.
- Также внутри цикла, каждого из этапов обработка контролирует структуру управления на наличия установленного свойства "Прервать". Если значение свойство равно "Истина", то прерывается задание. Тем самым демонстрируется обратная связь Фона с клиентским приложением.
- Дополнительно выводится свойство Состояние в Структуру Управления. Здесь отметим очень важное: Следует ограничить слишком частое обращение к Аддону (Структуре Управления) при обработке циклов. Если Вы очень часто записываете значения в структуру обмена, то это, при наличии большого числа работающих с Аддоном Фонов в этом процессе, замедлит работу всех этих Фонов. Поэтому чтобы не забивать работу, например той же самой обработки тестирования, которая интенсивно работает с компонентой. Я ограничиваю передачу значения Состояния и Индикатора не чаще чем через 1/20 секунды (50 мс) после последней передачи. В обработке можно увидеть как это реализовано.
- По окончании каждого этапа, записываем в Структуру Управления промежуточный результат работы компоненты в одно из свойств.
- Со стороны формы обработки, после запуска Фона (практически до запуска) выполняется Обработка Ожидания, каждый запуск которой инициирует обращение через сеанс к серверу загрузку текущего состояния Структуры Управления - всех свойств, можно ограничить загружаемые свойства по составу структуры, которую передаем этому сеансу. Она заполняет все свойства формы по полученным данным.
- После заполнения свойств формы по данным Структуры Управления, Обработка ожидания обращается ещё раз к сеансу сервера за получением структуры сообщений, когда Структура Сообщений отправляется Клиенту, все переданные этим вызовом Сообщения - удаляются из Аддона на сервере. Тем самым обеспечивается исключение дублирования, если несколько форм или обработок одновременно подключаются к этой Структуре Сообщений
- При нажатии кнопки "Прервать", любой из открытых форм обработок в этом серверном процессе, будет инициирована передача свойства "Прервать" находящимся там рабочему Фону и Роботу, если они активны.
Отличия варианта Взаимодействия с Фоном в режиме работы с Хранилищем Настроек от режима с Аддоном "Структура Обмена".
В целом в обработке я использовал тот же самый алгоритм, что и для варианта с Аддоном, только с небольшим отличием:
- Для определения какой вариант Взаимодействия будет использовать, обработки в клиентской части и серверной (Фоне) использует ПараметрСеанса УправлениеФоном, который инициализируется одноименной константой. Но так если у Вас несколько приложений (сеансов) отслеживает работу одного фона, то нужно во всех их перепрописать константу, чтобы обновился ПараметрСеанса.
- В Фоне вместо Аддона, процедура Тестирования получает обычную структуру 1С, т.е. Структура Управление и Структура Сообщений - это обычные структуры. Но после установки значений и перед чтением из структуры выполняются 1 функция чтения настроек и 1 процедура записи настроек. Функции находятся в общем модуле "ХранилищеНастроек". Они простые, ничего сложного, можете в Демо-версии посмотреть. Вот эти функции:
- Функция ПолучитьСтруктуруНастроекСервер(ИмяПараметра) - возвращает сохраненную структуру из Хранилища настроек по предопределенному ключу. Решил упростить и не передавать Ключ функции.
- Процедура СохранитьСтруктуруНастроекСервер(ИмяПараметра,НовоеЗначение) - записывает по предопределенному ключу переданную структуру.
- Далее в общем модуле, в функциях которые отвечают за синхронизацию (обмен с Фоном) включил проверку на параметр сеанса "УправлениеФоном" и соответственно чтение и запись структуры происходит через Хранилище настроек.
Существенные отличия варианта Взаимодействия в режиме работы С Хранилищем от Аддона:
- Достоинства:
- Возможность межпроцессной передачи значения, а также передачи значений между разными приложениями одного пользователя. Это преимущество пока временное, т.к. планируется функционал Аддона увеличить до обмена меж процессами и внутрисетевыми обменами.
- Возможность закрыть для других пользователей свои данные (проверка доступа), от Администратора - не получится закрыть. Для Аддона неактуально, так как все находится в памяти, а Фоны с Клиентом обмениваются через Общий модуль, в котором Администратор может проверку прав добавить самостоятельно, например через дополнительное Свойство "Пользователь" в Структуре Обмена. Также можно защитить Структуру - придумав ей Уникальное имя, хоть тот же Гуид.
- Недостатки:
- Контроль прав пользователя - замедляет процесс работы, но не защищает в случаях, если все имеют права Администратора
- Засорение Хранилища, после работы обработки - данные не исчезают сами по себе, если их явно не удалили по ключу. Если сбой в работе, или обработка прервалась, то данные так и остаются.
- Если Фоновый процесс упал, то в Хранилище может остаться данные о том что он как бы работает. В случае с падением Фона в режиме работы с Аддоном, Приложение сразу определит что Фона нет.
- Ненадежность обмена данными, потери возникают даже при интенсивной работе, даже когда всего 1 приложение мониторит Фон, из Сообщений не доходит от 1 до 2 из 16 сообщений. В случае с 5 приложениями, это число доходит до 4-х из 16 - 25 % потерь.
- Скорость обмена через Хранилище уступает Аддону от нескольких десятков до нескольких сотен раз. В Демонстрации когда тестировали производительность и затраты времени на Взаимодействие, по факту мы очень сильно завышали время выполнение Аддоном, т.к. при Взаимодействии интенсивно использовался Аддон самой обработкой, т.е. там максимально возможное количество блокировок было использовано. А с Хранилищем - наоборот занизили, т.к. в рабочих базах там это Хранилище довольно сильно заполнено и загружено запросами, а в системах с большим числом пользователей оно ощутимо медленнее будет работать. Приведу таблицу текущих расчетов по данным Замера производительности. По таблице мы видим что в среднем уже тут в неравных условиях производительность при чтении уступает раз в 27, при записи раз в 96 (около ста).
Результат замера производительности в миллисекундах (мс)Режим Запись ключ Запись (итер) След (итер) Запись (заплн.) Запись (встав.) Итого запись (мин) Итого запись (макс) Чтение ключ Чтение (итер) След (итер) Чтение (заплн.) Чтение (свой ство) Итого чтение (мин) Итого чтение (макс) Аддон без особой нагрузки, 16,7% строки до 1024, 16,7% двоичные данные от (1024 до 2048) 0,1112 0,0545 0,039 - 0,042 0,0723 0,111 0,0935 0,1112 0,0765 0,0367 - 0,0461 0,039 - 0,042 0,047 0,0997 - 0,1772 0,0757 0.0997 Аддон (структура до 8 свойств, 1 строка Состояние и 1 строка от 0 до 1850. Нагрузка : Тестирование + 2 сеанса с подписчиками) 0,0289 - 0,1752 0,2424 0,0289 0,8893 0,0408 0,1772 0,0408 0,1772 Хранилище настроек (структура до 8 свойств, 1 строка Состояние и 1 строка до 1850) 8,977 9,13 2,0496 2,289 Кратность времени ХН Аддону x 96 x 10,2 - x 82 x 27 - x 50 x 12,9 - x 23
Резюме и рекомендации.
- Преимущества. Какие преимущества мы получаем используя Аддон Структуры Обмена для работы с Фоном:
- Удобство проектирования самого фонового задания из-за прозрачности работы Аддона. После создания 1-й или 2-х Структур Управления и Сообщений, мы работаем с ними как с обычными структурами. Даже если не получится создать Аддон, программист может подсунуть обычную структуру и Фон ничего не будет об этом знать.
- Минимизация затрат времени на обмен, остается конечно затраты на вызов Сервера, в конечном счете это может быть нивелировано в будущих версиях, когда Клиент сможет через Аддон сразу подключаться к нужной структуре, используя SQL.
- Стабильность и надежность работы, даже в условиях когда удаляются и меняются свойства другим процессом. Отсутствие потерь данных из-за одновременного доступа к одному объекту.
- Обход некоторых ограничений. На 1С версиях 8.1 и 8.2 можно использовать данный Аддон, если у Вас всего один Активный процесс, обычно старые версии неинтенсивно используются и нет необходимости на них делать много процессов. Либо можно на процесс, который будет использоваться для запуска Фонов установить максимальную производительность 1000, а на остальные уменьшить до 10. В дальнейшем Аддон будет дорабатываться на межпроцессное взаимодействие и можно будет пользоваться и в этой версии 1С без ограничений.
- Совместимость: на текущий момент поддерживаются системы Windows Workstation от XP до 10 и Windows Server версий от 2003+. Платформы x32 и х64.
- Гибкость. Можно сделать реализацию, когда через переменную задаем в обработке в Фоне какой вариант Взаимодействия использовать, и если например, мы не нашли Робот Аддона в своем текущем сеанса или не проинициализирована Структура Управления формой УФ, то переключиться на вариант через Хранилище настроек. В будущем планируется доработка для межпроцессного взаимодействия и внутрисетевого.
- Универсальность. Аддон может запускаться в 3-х режимах: Компонента Native, компонента COM, OLE Auto (IDispatch). Последний режим запуска действует медленнее структуры раз в 10-12, но позволяет использоваться на серверах 8.0 и 8.1, где невозможен запуск любых компонент.
- Перспектива. Планируется добавить возможность обмениваться данными между структурами на разных процессах и разных компьютеров через файловый обмен, сервера MS SQL, MySQL, PostGre и другие. Также, при необходимости будет версия и для Unix, пока до этого далеко. Возможно расширения функционала для работы со строками, например, добавление или изъятие строки или добавление значения с преобразованием в строку - пока далеко и не существенно.
- Особенности и ограничения IDispatch. В частности, при использовании Аддона в режиме IDispatch на серверах 8.0 и 8.1:
- 1С использует кеширование DISPID свойств и методов, при этом если начиная с версии 8.1 он это делает до вызова любого метода, то в 8.0 это навсегда. Аддон же обладает динамическим набором свойств, поэтому Аддон в этом режиме учитывает, то что позиция свойства могла измениться и производит свое Декеширование свойств. В итоге и 1С и Аддон имеет 2 дополнительные таблицы на каждый объект - это замедляет работу Аддона в целом. Как я писал раз в 10-12 Аддон в этом режиме медленнее структуры 1С по результатам тестирования. Зато обеспечивается надежность работы со свойствами структур.
- 1С не имеет возможность получить список динамических свойств COMОбъекта, если они не заданы в библиотеке типов. Поэтому процедура ЗаполнитьЗначенияСвойств на чтение из Аддона не срабатывает без явно заданного списка свойств. На запись при этом все работает, так что можно в Аддон копировать структуру, но не наоборот.