В процессе разработки на платформе 1С:Предприятие 8 часто возникают ситуации, когда необходимо оптимизировать выполнение тяжелых функций или минимизировать количество обращений к внешним сервисам (API сайтов, серверы лицензирования, сложные расчеты). Одним из самых эффективных и простых инструментов для этого является механизм Повторного использования возвращаемых значений. Рассмотрим подробно, как он работает, какие существуют нюансы и как избежать типичных ошибок при его настройке.
Когда мы устанавливаем свойство «Повторное использование возвращаемых значений» для функции в общем модуле, платформа включает режим кэширования. Проанализируем, что происходит при вызове такой функции:
Разберем практический пример. Допустим, у нас есть функция получения курса валюты или проверки лицензии на внешнем сервере. Без кэширования каждый вызов будет занимать 1–2 секунды на сетевое взаимодействие. С включенным повторным использованием повторный вызов произойдет мгновенно.
// Функция в общем модуле с включенным повторным использованием
Функция ПолучитьДанныеСВнешнегоСайта(ИдентификаторЗапроса) Экспорт
// Этот код выполнится только один раз за период жизни кэша для каждого Идентификатора
НТТР = Новый HTTPСоединение("api.service.com");
Запрос = Новый HTTPЗапрос("/data/" + ИдентификаторЗапроса);
Ответ = НТТР.Получить(Запрос);
Возврат Ответ.ПолучитьТелоКакСтроку();
КонецФункции
Платформа предлагает две принципиально разные настройки для этого механизма, которые важно различать:
1. На время вызова сервера. Кэш существует только в рамках одного «похода» с клиента на сервер. Это полезно, если внутри одной сложной транзакции или обработки одна и та же функция вызывается сотни раз (например, поиск настроек в справочнике). Как только управление вернется на клиента, кэш будет очищен.
2. На время сеанса. Это наиболее мощный режим. Данные хранятся в памяти сервера в течение всего времени работы пользователя в программе (с учетом временных лимитов). Именно этот вариант мы используем для оптимизации работы с внешними API и тяжелыми запросами.
Нужно понимать, что кэш не вечен. Платформа 1С автоматически управляет его очисткой, чтобы не допустить переполнения оперативной памяти сервера. Выясним основные правила удаления данных из кэша:
rphost заканчивается оперативная память, кэш может быть сброшен принудительно.Посмотрим на ситуацию: если мы запрашиваем лицензию раз в 5 минут, то технически мы можем никогда не выйти за предел 6 минут, и теоретически данные могут жить долго (до 20-минутной отсечки). Это отлично подходит для задач, где небольшая задержка в обновлении данных (актуальность раз в 20 минут) не является критичной.
Не любую функцию можно сделать «повторно используемой». Существуют жесткие правила платформы:
Параметры функции: можно передавать только простые типы (Число, Строка, Дата, Булево), ссылки на объекты базы данных (СправочникСсылка, ДокументСсылка) или системные перечисления. Нельзя передавать объекты (например, СправочникОбъект) или структуры, так как платформа не может гарантировать корректное сравнение их состояний для поиска в кэше.
Возвращаемые значения: функция не должна возвращать мутабельные (изменяемые) значения, такие как ТаблицаЗначений или ДеревоЗначений. Обычно возвращаются простые строки, числа или фиксированные структуры/массивы. Если вам нужно вернуть таблицу, лучше преобразовать ее в массив структур или строку JSON.
Важный момент, который часто упускают разработчики: что произойдет, если код функции вызовет ошибку? Рассмотрим поведение системы:
Если внутри функции сработает оператор ВызватьИсключение, то результат выполнения не будет закеширован. Платформа считает, что успешного возврата значения не произошло. При следующем вызове функции код будет запущен заново. Это логично: если сайт был недоступен, мы хотим попробовать обратиться к нему снова при следующем запросе, а не «запоминать» ошибку на 20 минут.
Иногда возникают ситуации, когда нам нужно принудительно обновить данные, не дожидаясь истечения таймеров. Например, пользователь нажал кнопку «Обновить данные с сайта». В 1С предусмотрен специальный метод для этого:
ОбновитьПовторноеИспользованиеЗначений();
Этот метод полностью очищает кэш повторного использования для текущего сеанса. Будьте осторожны: он очищает кэш всех функций во всех модулях, а не какой-то конкретной. Также кэш может сбрасываться при вызове метода ОповеститьОбИзменении(), если кэшируемые данные связаны с объектами БД.
Проанализируем поведение конфигуратора при отладке таких модулей. Если вы установите точку останова внутри функции с повторным использованием, вы заметите странность: при первом вызове отладчик остановится на коде, а при втором и последующих — проигнорирует её. Это происходит потому, что платформа физически не заходит в тело функции, а берет значение из памяти.
Для отладки таких функций рекомендуется либо временно менять параметры вызова, либо на время разработки отключать флаг повторного использования в свойствах модуля.
Разберем работу в многопоточной среде. Важно помнить:
rphost, кэш будет создан заново.Механизм повторного использования — это не замена полноценному хранилищу данных, а инструмент оперативного кэширования. Он идеально подходит для:
Используйте этот инструмент осознанно, помните о лимитах в 20 минут и ограничениях типов данных, и ваша система станет работать значительно быстрее, избавляясь от лишних секунд ожидания на каждом шагу.