Глобальные переменные в контексте сервера #476297


#0 by Kaidend
Всем привет. Есть достаточно большой код (несколько общих модулей, десятки процедур и функций), опирающийся на использование глобальных переменных, объявленных в модуле приложения. Код выполняет обмен между базой 1С и системой Оптимум (мобильная торговля). Требуется сделать так, что бы этот код исполнялся по расписанию. Использую для этих целей регламентные задания. Поскольку база работает в клиент-серверном режиме, задания выполняются на сервере. На сервере глобальных переменных нет, код становится нерабочим. Можно, конечно, собрать все глобальные переменные в одну структуру и передавать их каждой процедуре при каждом вызове. Можно отказаться от регламентых заданий в пользу запуска bat-файла по расписанию планировщика ОС. Но мне интересно - неужели нет никакого способа для "эмуляции" глобальных переменных на стороне сервера? Пусть бы они и жили только пока выполнялась бы "родительская" функция, запустившая некоторый процесс на сервере.
#1 by Stepa86
ПараметрыСеанса?
#2 by Kaidend
Проблема в том, что эти глобальные переменные имеют тип структура и таблица значений. Параметры сеанса такой тип иметь не могут...
#3 by Господин ПЖ
>Есть достаточно большой код (несколько общих модулей, десятки процедур и функций), опирающийся на использование глобальных переменных, объявленных в модуле приложения. за такие штуки eggs отбивать надо
#4 by nop
не надо. ХранилищеЗначения ?
#5 by fisher
Статическую коллекцию можно запихать в "ФиксированныйМассив" С динамическими сложнее. Их можно паковать в "ХранилищеЗначений". Но при частом использовании в цикле лучше дополнительно кэшировать на клиенте (паковка/распаковка довольно затратны по времени).
#6 by fisher
На 8.2 есть прикольный финт ушами через общие модуля с повторным использованием возвращаемых значений.
#7 by Kaidend
Там глобальными переменными не злоупотребляют, их немного и они действительно нужны. С хранилищем значения - мысль, но одна из этих переменных (таблица значений) довольна большая и в каждой процедуре ее упаковывать/распаковывать как-то не очень, плюс однотипный код в каждой процедуре... По всей видимости, буду таки исправлять вызовы процедур.
#8 by fisher
И каким образом планируешь "исправлять вызовы процедур"? Просто интересно...
#9 by Kaidend
Ну я в написал. В стартовой процедуре объявлем структуру, добавляем туда элементы, ключи - названия наших глобальных переменных. Далее при каждом вызове процедуры эта структура передается "по цепочке", от вызывающей процедуры к вызываемой. В текстах самих процедур обращение к глобальной переменной на обращение к структуре можно будет заменить с помощью глобального поиска и замены.
#10 by fisher
Дык а хранить твою таблицу между сеансами обмена где? Каждый раз инициализировать?
#11 by Kaidend
А табличку не надо хранить между сеансами обмена. Табличка - это протокол обмена, в конце обмена она преобразуется в табличный документ и сохраняется на диске. Вообще, кажется, я нашел нормальное решение. Метод регламентного задания будет вызывать процедуру ЗапуститьСистему, которая запустит 1С от имени специального пользователя и в качестве параметра запуска передаст имя настройки, по которой должен выполняться обмен. В обработчкие ПриНачалеРаботыСистемы будет проверяться, от имени какого пользователя работаем, и, если это наш специальный пользователь, выполняем обмен по указанной настройке и завершаем работу системы.
#12 by fisher
Ну ты извращенец. Использовать регламентное задание как виндовый шедулер - это цирк. Если между сеансами хранить не надо - делай как сразу решил. Передавай параметром между всеми процедурами обмена. Самое правильное решение.
#13 by Kaidend
Можно и Win-планировщик использовать, вариант в действительно не без изврата. Хотя что использование внешнего планировщика при наличии у 1С своего собственного, что передача в каждую процедуру при каждом вызове одного и того же аргумента - приемы одинаково кривые. Я еще подумаю, какой из них наименее кривой, его и выберу. Жаль, что в 1С нет механизма, позволяющего использовать глобальные переменные в ходе одного "сеанса работы" сервера, не вижу для этого никаких принципиальных ограничений.
#14 by fisher
"передача в каждую процедуру при каждом вызове одного и того же аргумента" - приём ни разу не кривой, а очень даже стандартный и правильный. Намного правильнее, чем использовать глобальные переменные. Почему сам догадаешься, или нужно классику перечитать?
#15 by Kaidend
Ммм, смотрите, у меня есть потребность в трех переменных, которые были бы доступны в нескольких процедурах и функциях. Две из этих переменных нужны только одной функции, которая вызывается множеством других функций (можно было бы объявить ее с ключевым словом static, если бы 1С такое поддерживала), и одна переменная нужна многим функциям. Есть два варианта: 1) Объявить три глобальные переменные, присвоить им нормальный префикс, очищать их содержимое в начале и конце обмена. Это с вероятностью 99% исключит случайное изменение значения этих переменных и другие возможные ошибки, связанные с расширением глобального контекста. 2) "Изуродовать" вызов каждой процедуры передачей того, что она могла бы взять сама. Код станет "тяжелее" и избыточнее за счет увеличения числа формальных и фактических параметров и использования конструкций типа имяСтруктуры.ИмяПеременной вместо имяГлобПеременной. А теперь объясните мне, пожалуйста, чем второй вариант лучше первого, кроме того, что он "стандартный", "правильный", "как в классике" и прочее пустословие? Нормальная классика, кстати говоря, учит думать и понимать, а не слепо следовать каким-то правилам.
#16 by Defender aka LINN
"Нормальная классика, кстати говоря, учит думать и понимать, а не слепо следовать каким-то правилам." - ну, думай, понимай, смотри дальше в нерабочую конфигурацию.
#17 by Jolly Roger
нужно, просто, "сконвертировать" общие модули в обработки...
#18 by Kaidend
А с чего вы взяли, что она у меня нерабочая? Захотелось щеки лишний раз надуть?
#19 by Defender aka LINN
То есть, у тебя код на сервере работает без проблем, да?
#20 by Kaidend
А мне не нужно, чтобы код обязательно работал на сервере :) Мне главное, чтобы код работал по расписанию, а серверный процесс его будет выполнять или клиентский - мне не важно. Я в вообще немного о другом писал.
#21 by Defender aka LINN
Значит, у тебя нерабочая конфигурация.
#22 by Kaidend
Т.е. моя конфигурация, реализуя весь требуемый от нее функционал, является нерабочей? Как там щеки, не лопнули еще?
#23 by Defender aka LINN
Представь себе, нет. Твоя конфигурация не работает на сервере. В режиме внешнего соединения, я так понимаю, тоже. То есть, работать в ней можно только в клиентском режиме. Это не конфигурация уже получается, а кусок гуано. У тебя, похоже, очень крепкая лобовая кость, раз стукнувшись об ты продолжаешь считать, что что-то сделал правильно.
#24 by Kaidend
Хуже того - моя конфигурация не готовит налоговую отчетность, не рассказывает пользователем анекдоты и не способна пилотировать космический корабль. Делает ли это ее "куском гуано"? Думаю, что нет. Она делает все то, что должна делать, а когда возникают новые потребности (как в ), то их можно реализовать. Может, решение будет не очень красивым, но конфигурация была и будет рабочей.
#25 by Kaidend
Кстати, стукнувшись головой об я понял, что использовать глобальные переменные в коде, который предположительно будет работать на сервере, в принципе нельзя. Чего я не могу понять - какого черта вы вылезли в с воплями о нерабочей конфигурации, когда я просто столкнулся со вполне решаемой сложностью и описал пути ее решения в ? Хотя нет, я это тоже понимаю - обычное сочетание высокого самомнения, низкой культуры общения и, видимо, каких-то глубоких комплексов. Никак не могу приучить себя не реагировать на таких персонажей, ужасно раздражают ((
#26 by Defender aka LINN
Скучно было, решил дятлов погонять. Раз понял, то хорошо, может что и получится.
#27 by Kaidend
Проще говоря - поднять себе самооценку наиболее примитивным методом. Впрочем, я тоже получаю некоторое удовольствие от осаживания самоуверенных ослов, признаться. Ладно, проехали. Можете что-нибудь написать, чтобы последнее слово осталось за вами, я не потружусь отвечать :)
#28 by acsent
Сделай обработку, там можно сколь угодно "глобальных" переменных использовать
#29 by Kaidend
Я уже сделал запуск клиентского сеанса по расписанию. Использовать обработку не хотелось бы потому, что код в общих модулях разделен по выполняемой задаче, ориентироваться потом в одном объединенном модуле будет сложнее. Была бы возможность создавать несколько модулей в одной обработке - так бы и сделал.
#30 by acsent
Несколько обработок
#31 by acsent
Тогда уж лучше через обработку ожидания
#32 by Kaidend
Несколько обработок нужно увязывать между собой, т.е. код перетряхивать. Чем лучше?
#33 by acsent
Нужно запустить только 1 сеанс. Так делаяются онгламентные задания в файловых версиях
#34 by fisher
Ничего уродовать не надо. Создаешь одну структуру с именем "КонтекстСеансаОбмена" (к примеру) и используешь в параметрах нужных тебе функций.
#35 by fisher
+ Теперь на пальцах, чем такой вариант лучше (раз классики мы не знаем, но следовать ей заранее не хотим). 1) конфликты пространств имен и прочие трудновыловимые ошибки связанные с использованием глобальных переменных исключаются В ПРИНЦИПЕ и НАВСЕГДА. А не "на сейчас", пока ты всё помнишь и в голове держишь. 2) читабельность/сопровождение процедур, использующих только данные из своих параметров (это называется инкапсулированность) намного выше. Ибо совершенно постороннему человеку (читай, тебе же через годик) будет достаточно одного взгляда на заголовок процедуры, чтобы понять, что она использует какой-то "КонтекстСеансаОбмена". Что это, где и как инициализируется - тут же в момент выясняется. Дальше можно вообще не смотреть - в большинстве случаев достаточно понять, что на входе и на выходе. А вот то, что внутри используются не пойми какие глобальные переменные, влияющие на её работу - нихрена не очевидно.
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям