При интеграции 1С со сторонними сервисами разработчики часто выносят логику API во внешние обработки (файлы .epf). Нередко возникает желание работать с такой обработкой как с долгоживущим объектом-классом: один раз инициализировать экземпляр, передать туда параметры авторизации и затем на протяжении всего пользовательского сеанса многократно вызывать его методы без постоянного пересоздания объекта. Разберем, с какими платформенными ограничениями мы сталкиваемся на управляемых формах и как правильно организовать архитектуру такого решения.
Проанализируем архитектуру клиент-серверного взаимодействия платформы 1С:Предприятие 8.3 на управляемых формах:
rphost обрабатывают запросы независимо. Создать долгоживущий объект типа ВнешняяОбработкаОбъект и удерживать его в оперативной памяти сервера на все время работы пользователя невозможно.ВнешняяОбработкаОбъект в ПараметрыСеанса или во ВременноеХранилище.Выясним причину, по которой требуется постоянное удержание экземпляра в памяти. Как правило, это необходимость сохранять авторизационный токен, куки или идентификатор сессии стороннего API. Правильный архитектурный подход заключается в разделении состояния и исполняемых методов:
HTTPСоединение и возвращают ответ.Если логика должна оставаться в файле на диске, постоянное чтение файла с накопителя через Новый ДвоичныеДанные() создает лишнюю нагрузку. Однако метод ВнешниеОбработки.Подключить() позволяет скомпилировать и зарегистрировать обработку во внутреннем кэше рабочего процесса сервера. После этого создание экземпляра через ВнешниеОбработки.Создать() происходит практически мгновенно из оперативной памяти.
Рассмотрим пример функции-фабрики для получения объекта обработки. Учтем, что в кластере серверов может быть несколько рабочих процессов rphost, поэтому подключение нужно оборачивать в попытку:
Функция ПолучитьОбъектИнтеграции() Экспорт
ИмяПодключения = "ВнешнийСервисAPI";
Попытка
// Пробуем создать объект из уже зарегистрированного в процессе модуля
Возврат ВнешниеОбработки.Создать(ИмяПодключения, Ложь);
Исключение
// Если в текущем rphost обработка еще не подключена, читаем и подключаем
ПутьКФайлу = "E:\Обработки\API\API.epf";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла);
ИмяПодключенной = ВнешниеОбработки.Подключить(АдресХранилища, ИмяПодключения, Ложь);
Возврат ВнешниеОбработки.Создать(ИмяПодключенной, Ложь);
КонецПопытки;
КонецФункции
Обратим внимание на обязательную передачу параметра Ложь (безопасный режим). Если подключить обработку в безопасном режиме (по умолчанию Истина), платформа 1С заблокирует исходящие сетевые запросы и обращение к файловой системе.
Рассмотрим альтернативы, которые избавляют от необходимости манипулировать внешними файлами на диске:
ДополнительныеОтчетыИОбработки (БСП). Механизмы БСП берут на себя версионирование, размещение во временных файлах и вызов серверных процедур.Иногда предлагают поместить получение обработки в общий модуль с признаком Повторное использование возвращаемых значений на время сеанса. Посмотрим на особенности этого метода:
Платформа 1С проектировалась так, чтобы кэшировать только неизменяемые структуры данных (выборки, структуры, массивы). Кэширование объектов типа ВнешняяОбработкаОбъект через кэш общих модулей крайне не рекомендуется: это приводит к утечкам оперативной памяти в рабочих процессах rphost, трудноуловимым ошибкам многопоточности и непредсказуемому сбросу состояния при очистке системного кэша платформы.