Имя: Пароль:
1C
 
Параметр сеанса
0 repin_mike
 
09.02.21
17:36
Разъясните как пользоваться параметрами сеанса. Мне бы надо где-то хранить переменную нужного типа, я собственно и думал что параметр сеанса это такая типа глобальная переменная. Оказалось, что вообще не так: сначала выяснилось, что параметр сеанса надо инициализировать любым значением, иначе при попытке чтения ошибка. Потом выяснилось, что это надо делать в модуле сеанса в УстановкаПараметровСеанса, при этом в хелпе написано что с ТребуемыеПараметры = Неопределено это событие вызывается только один раз при старте системы. Теперь вот выяснилось, что УстановкаПараметровСеанса с параметром Неопределено вызывается каким-то фоновым заданием, и соответственно мой параметр сеанса переинициализируется. Подскажите плз.
1 polosov
 
09.02.21
17:47
2 repin_mike
 
09.02.21
18:13
(1) Я это и читал. У меня отладчик показывает, что УстановкаПараметровСеанса с параметром Неопределено вызывается каким-то фоновым заданием, которое откуда-то срабатывает в момент попытки чтения моего параметра сеанса, соответственно он переинициализируется и считывается уже кривым. И в хелпе, и в вашей статье написано, что УстановкаПараметровСеанса с параметром Неопределено вызывается только один раз в момент старта системы, но я вижу что это  не так
3 Вафель
 
09.02.21
18:30
вообще при чтении должен сам вызвать установку в 1 раз
4 repin_mike
 
10.02.21
09:18
А возможно создать в управляемых формах глобальную переменную, которая будет видна из любого модуля (общего, объекта, формы)?
5 ДенисЧ
 
10.02.21
09:20
(4) нет
6 Новый1сник2
 
10.02.21
09:20
(4) константой можно сделать
7 repin_mike
 
10.02.21
09:30
(6) Константа одинакова для всех пользователей, а мне нужна привязка к конкретному сеансу пользователя
8 arsik
 
гуру
10.02.21
09:30
(2) Это чей то говнокод похоже
9 arsik
 
гуру
10.02.21
09:34
У нас сделано так:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
    Если ТребуемыеПараметры = Неопределено Тогда
        Возврат;
    КонецЕсли;
10 repin_mike
 
10.02.21
10:05
(8) Можете концепцию объяснить, я пока вообще ничего не понимаю. Если бы этот механизм делал я, то нет ничего проще - параметр сеанса это глобальная переменная, которая видна из любого места, при этом в каждом сеансе каждого пользователя он свой, то есть если в одном сеансе я этот параметр поменял, то в другом сеансе другого пользователя этот параметр сеанса не изменился. С тех пор, как подобный параметр сеанса описан в конфигураторе и ему присвоен тип, он уже прям сразу доступен для чтения, например если я описал ему тип Справочник.ФизическиеЛица, то я читаю ПараметрыСеанса.МоёФизлицо и там лежит пустая ссылка. При такой концепции ни инициализация, ни модуль сеанса не нужны от слова совсем.

Теперь то, как оно на самом деле происходит. После запуска программы, несмотря на то, что МоёФизлицо описано в конфигураторе, чтение ПараметрыСеанса.МоёФизлицо дает ошибку. В хелпе написано что его за каким-то лядом надо инициализировать, причём ПриНачалеРаботыСистемы его инициализировать не получается, а только в модуле сеанса, который тоже непонятно зачем выдумали. Ну ОК, в модуле сеанса типа есть Процедура УстановкаПараметровСеанса(ТребуемыеПараметры), причём в хелпе написано что эта процедура вызывается один раз с ТребуемыеПараметры = Неопределено в момент старта системы, а в следующие разы оно срабатывает когда надо какой-то параметр сеанса переинициализировать (нафейхоа?) и типа их массив как раз в ТребуемыеПараметры и лежит. При этом, если поставить брейкпойнт при УстановкаПараметровСеанса, то в ПараметрыСеанса коллекция пустая, несмотря на то, что в конфигураторе их описано сто штук. И как вишенка на торте я вижу, что УстановкаПараметровСеанса вызывается много раз с ТребуемыеПараметры = Неопределено, в том числе не только при начале работы системы, а как раз перед тем, как в совершенно другом модуле совершенно другой обработки я этот параметр читаю. Получается, что если мой параметр сеанса не инициализировать, то его и прочитать не получится, а если прописать в коде инициализацию, то оно будет переинициализироваться каждый раз перед чтением. Видимо я не совсем понимаю концепцию разработчиков этого механизма, а в справке об этом не написано.
11 Волшебник
 
10.02.21
10:13
(10) Инициализируйте наконец параметр сеанса в модуле сеанса в процедуре УстановкаПараметровСеанса.
Если в ТребуемыеПараметры равно Неопределено, а параметр сеанса вам будет нужен, то инициализируйте его, несмотря на Неопределено.
12 LoneBull
 
10.02.21
10:23
(0)
>УтановкаПараметровСеанса с параметром Неопределено вызывается каким-то фоновым заданием
Как бы, у фоновых заданий свои сеансы -> в любом фоновом задании будет вызова УтановкаПараметровСеанса с Неопределено.
13 Волшебник
 
10.02.21
10:24
(10) параметр сеанса надо переинициализировать, если он изменился по бизнес-логике. Например, в параметрах сеанса хранится параметр доступа "Доступные объекты" и админ изменил права доступа. Пользователю можно перезайти в систему, а можно просто нажать кнопку "Обновить". По кнопке "Обновить" Ваш программный код заново инициализирует параметры сеанса, а потом вызовет обновление динамического списка, чтобы сработали новые RLS.
14 fisher
 
10.02.21
10:35
(0) Невнимательно читал. Неинициализированные параметры использовать нельзя - это защита от дурака. Но при первом обращении к неинициализированному параметру сеанса платформа дернет для программиста УстановкаПараметровСеанса с указанием, какой параметр необходимо проинициализировать. И вот если и тогда он не будет проинициализирован - тогда будет исключение.
(4) Ну, ходи из УФ за своим параметром сеанса на сервер. Сделай для этого функцию клиент-серверного общего модуля, чтобы если обращение с клиента - то ходило на сервер за ней.
В старых типовых на ОФ когда-то была подобная говносистема глобальных переменных, охватывающая и клиента и сервер. Но потом от нее отказались, слава богу. Потому что злоупотребление глобальным контекстом - это всегда костыли, чреватые боком. Да и в УФ это особо неэффективно. Да и особенно чревато в силу повсеместной асинхронности.
15 fisher
 
10.02.21
10:40
Если нужно банальное кэширование, то это эффективно делать "по месту". А на уровне общих модулей вообще есть готовый механизм повторного использования возвращаемых значений.
16 fisher
 
10.02.21
10:44
(2) Да. С параметром Неопределено вызывается один раз. Когда-то оно вообще один раз и дергалось. Но в новых версиях 1С для ускорения старта программы реализовали отложенную инициализацию. Чтобы при старте приложения можно было инициализировать необходимый минимум параметров, а остальное - при первом обращении.
17 repin_mike
 
10.02.21
10:50
(16) Могу скриншоты показать. По-видимому, (12) прав, у фонового задания свои параметры сеанса

Задача: пользователь в какой-то момент времени ввел пароль и система его запомнила до момента закрытия платформы, и пароль можно считать из любого места (модуль формы, модуль объекта, функция общего модуля, которая вызывается из СКД отчёта, а отчёт СКД, судя по всему, выполняется фоновым заданием, у которого свои параметры сеанса). Записывать в базу пароль, естественно, нельзя.
18 fisher
 
10.02.21
11:40
(17) ИМХО, фоновые задания созданные из сеанса пользователя, используют его параметры сеанса. Иначе никакой отчет СКД при выполнении в фоне не смог бы использовать RLS, завязанные на параметры сеанса. Вот фоновые, созданные регламентными заданиями - те да.
ЗЫ. Общая практика - не хранить пароль вообще никак и никогда. Провел аутентификацию, выдал права (провел авторизацию) - дальше просто используешь эти права.
19 repin_mike
 
10.02.21
11:54
(18) Там шифровать/расшифровывать надо "на лету", соответственно солёный пароль необходим.
20 fisher
 
10.02.21
12:11
(19) Тогда и говорить лучше не про пароль, а про ключ шифрования. Прямая задача пароля - аутентификация. Лучше сразу не смешивать понятия - может аукнуться.
Ну а так-то - да. Пишешь ключ шифрования в параметр сеанса и потом используешь. На старте по Неопределено инициализируешь каким-то дефолтным значением, которое в бизнес-логике интерпретируешь как пустое.
Не очень понятно, на чем ты споткнулся. То, что у тебя отчет формируется в фоне с пустым ключом шифрования - это не больше чем твое предположение, насколько я понял. Ну так проверь его. По-идее, все там должно быть в порядке.
21 LoneBull
 
10.02.21
13:01
(17)
>ИМХО, фоновые задания созданные из сеанса пользователя, используют его параметры сеанса.
От "родительского" сеанса берутся только параметры сеанса со значения разделителей.

>Иначе никакой отчет СКД при выполнении в фоне не смог бы использовать RLS
Руками (а не тем, на чём сидят) сделанный RLS использует только параметры сеанса инициализируемые "по запросу" (через УстановкаПараметровСеанса) - они просто инициализируются в сеансе фонового задания так же как и в родительском (если при этом в БД что-то поменялось - значения могут и разойтись).

>ИМХО
Ну можно ещё какую-нибудь теорию придумать и выложить на мисту. Она ведь для этого и нужна чтобы на работе bash.org не открывать (да и зачем, когда миста есть).
22 Anton1307
 
10.02.21
13:15
(0) 1. Инициализировать параметры сеанса ты можешь в любом месте программы в серверном коде
2. Читать неинициализированные параметры сеанса нельзя - вывалится исключение
3. При попытке чтения неинициализированного параметра сеанса вызывается УстановкаПараметровСеанса(<ИмяПараметра>) в модуле сеанса, с именем требуемого параметра. Здесь тебе дают последний шанс инициализировать параметр. Если ты и здесь этого не сделаешь - вывалится исключение (см. пункт 2)
4. При старте программы один раз вызывается УстановкаПараметровСеанса(Неопределено) в модуле сеанса. Здесь ты можешь провести первоначальную инициализацию параметров сеанса, например заполнить неизменяемые (например, ТекущийПользователь). А можешь ничего не делать - решать тебе
5. Параметры сеанса в клиентском приложении и в запущенном из него фоновом задании общие. В этом вся суть параметров сеанса - из-под одного сеанса может быть несколько подключение к базе

Так что смело используй параметры сеанса в качестве глобальной переменной.
Только не забудь её первоначально инициализировать (присвоить ей значение, пусть даже пустое)
23 acht
 
10.02.21
13:24
(22) > Параметры сеанса в клиентском приложении и в запущенном из него фоновом задании общие
Нет.
24 fisher
 
10.02.21
13:27
(22)(23) Да, вы правы. В каждом фоновом свои параметры и своя инициализация.
25 fisher
 
10.02.21
13:29
Тогда у ТС действительно проблема с пробросом ключа шифрования, вводимым пользователем.
26 Anton1307
 
10.02.21
13:30
(23) Вы правы... Действительно - нет...
Блин, а почему у меня тогда работает тот код по фоновой загрузке.
Полтергейст, мля...
27 fisher
 
10.02.21
13:33
Единственный вариант, который приходит в голову - это выполнять в отчете собственную фоновую компоновку вместо автоматической и пробрасывать туда ключ шифрования.
28 fisher
 
10.02.21
13:37
Если конфа типовая с "Вариантами отчетов" - то там и так кажись фоновая компоновка переопределяется, так что минимумом правок можно обойтись.
29 repin_mike
 
10.02.21
14:14
(27) Если я переопределю ПриКомпоновкеРезультата в отчёте, возможно, это поможет. Сейчас проверю.
30 repin_mike
 
10.02.21
14:27
(29) При самостоятельной компоновке вычисляемые поля не работают теперь. Сейчас разбираюсь.
31 fisher
 
10.02.21
14:47
(29) Конечно, поможет. Потому что при этом сразу накрывается тазом автоматическая фоновая компоновка. Твоя компоновка будет выполняться синхронно в том же процессе (и при долгом формировании программа у пользователя будет "висеть"). Если захочешь фоново - придется это все "руками" организовывать.
(30) При программной компоновке нужно явно разрешить использование внешних функций. В одном из параметров инициализации процессора компоновки.
32 repin_mike
 
10.02.21
17:15
(31) Спасибо огромное, всё заработало, правда пришлось ещё свою формуотчета добавить.
33 repin_mike
 
10.02.21
17:49
(32) Блин! Теперь, если добавить форму в отчёт, то во-первых отваливается оформление Макет оформления отчёта СКД слетает, если в отчёт добавить форму отчёта уже писал об этом.
А во-вторых по какой-то причине все ссылки в отчёте перестают быть ссылками, то есть при двойном клике не открываются.
И если первое черт с ним, то второе критично. Никто не знает что с этим можно сделать?
Программист всегда исправляет последнюю ошибку.