При исследовании механизмов запуска конфигурации, например 1С:Управление торговлей 10.3 последних редакций (включающих подсистемы БСП), разработчики нередко сталкиваются с загадочным поведением платформы: при установке точки останова в самом начале процедуры УстановкаПараметровСеанса модуля сеанса значение ПараметрыСеанса.ТекущийПользователь уже оказывается заполненным, хотя явное присвоение еще не выполнялось. Разберем детально, как устроена инициализация параметров сеанса на платформе 1С:Предприятие, как отладчик меняет естественный ход программы и как правильно локализовать момент заполнения параметров.
Проанализируем базовый принцип работы платформы с параметрами сеанса. В 1С используется модель отложенной (ленивой) инициализации. До момента первого обращения значение любого параметра сеанса является неопределенным. Обработчик события УстановкаПараметровСеанса в модуле сеанса вызывается не только один раз при старте приложения, но и каждый раз, когда код пытается прочитать значение еще не инициализированного параметра.
В процедуру передается ключевой параметр ТребуемыеПараметры:
ТребуемыеПараметры может иметь значение Неопределено, что сигнализирует о необходимости выполнения базовой стартовой инициализации сеанса.ТребуемыеПараметры массив строк с именами тех параметров, которые запрошены в данный момент. Логика конфигурации проверяет наличие имени в массиве и инициализирует только его.Если после завершения обработчика значение запрошенного параметра сеанса так и осталось не установленным, платформа генерирует исключение: «Попытка получения неинициализированного значения параметра сеанса».
Выясним причину, почему при остановке в модуле сеанса параметр ТекущийПользователь уже оказывается заполнен. Виновником такого поведения выступает сам отладчик Конфигуратора. Если выражение ПараметрыСеанса.ТекущийПользователь добавлено для отслеживания в окно «Табло», происходит следующее:
УстановкаПараметровСеанса модуля сеанса.ПараметрыСеанса.ТекущийПользователь расценивается платформой как обращение к неинициализированному параметру сеанса.УстановкаПараметровСеанса, передав в ТребуемыеПараметры массив со значением "ТекущийПользователь".СтандартныеПодсистемыСервер и ПользователиСлужебный), и параметр заполняется ссылкой на текущего пользователя.Аналогичный скрытый эффект провоцируют:
Посмотрим на реальную последовательность событий при старте клиента (например, в УТ 10.3 с внедренными механизмами БСП), когда отладчик не вмешивается в процесс:
УстановкаПараметровСеанса() с базовым набором параметров (или ТребуемыеПараметры = Неопределено). На этом этапе ТекущийПользователь еще не заполняется.ПередНачаломРаботыСистемы().
Функция АвторизованныйПользователь() Экспорт
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
УстановитьПривилегированныйРежим(Истина);
Возврат ?(ЗначениеЗаполнено(ПараметрыСеанса.ТекущийПользователь),
ПараметрыСеанса.ТекущийПользователь,
ПараметрыСеанса.ТекущийВнешнийПользователь);
#Иначе
Возврат СтандартныеПодсистемыКлиентПовтИсп.ПараметрыРаботыКлиентаПриЗапуске().АвторизованныйПользователь;
#КонецЕсли
КонецФункции
ПараметрыСеанса.ТекущийПользователь снова направляет поток выполнения в модуль сеанса — УстановкаПараметровСеанса().СтандартныеПодсистемыСервер.УстановкаПараметровСеанса().ПользователиСлужебный.УстановкаПараметровСеанса(), где по имени пользователя информационной базы ищется элемент справочника Пользователи и окончательно присваивается параметру сеанса.Разберем практические рекомендации, которые позволят увидеть реальную картину инициализации без искажения отладочной средой:
ПараметрыСеанса.ТекущийПользователь в результатах замера можно безошибочно определить точную строчку кода и модуль, где фактически произошло присвоение.УстановкаПараметровСеанса модуля сеанса:
Если ТребуемыеПараметры = Неопределено Тогда
СтрокаПараметров = "Все параметры";
Иначе
СтрокаПараметров = СтрШаблон("%1", СтрСоединить(ТребуемыеПараметры, ", "));
КонецЕсли;
ЗаписьЖурналаРегистрации(
"Инициализация параметров сеанса",
УровеньЖурналаРегистрации.Информация,,,
СтрокаПараметров
);
Обратим внимание на важное платформенное ограничение: при инициализации параметров сеанса поиск элементов справочников или чтение настроек обязательно должны выполняться с вызовом УстановитьПривилегированныйРежим(Истина). Если запрос к данным выполняется без привилегированного режима, а на таблицы наложены ограничения доступа (RLS), платформа внутри RLS-шаблона снова попытается прочитать параметры сеанса (в том числе текущего пользователя). Это вызовет бесконечную рекурсию, аварийный сбой и ошибку о попытке чтения неинициализированного значения.