Форум сайта python.su
Всем здравствуйте. Может кто сталктвался с данной проблемой и подскажет как решать?
Проблема следующая (возможно реализция покажется кому то не правильной. но что есть то есть)
Есть проект, в котором описаны публикуемые классы и не публикуемые. (объекты этих классов, насколько я понимаю, находятся в ZODB , когда его добавили в ZODB через ZMI а потом они просто “поднимаются” оттуда.)
публикуемые объекты поднимаются неявно, при запросе страници описанной для этого объекта (объект является контекстом вида)
при этом в каждом публикуемом объекте создайтсе некоторый объект авторизации
self.AuthNonePublic = AuthNonePublic(context, request)
Ну и у этого объекта есть наборы методов и переменных, одна из которых - соварь. И всё прекрасно работает, за исключением следующего:
Например если есть пользователь1 и пользователь2. Оба одноврименно запросили страницу А или Б
пользователь1 пользователь2
страница A Б С D
публикуемые объекты
объект авторизации (AuthNonePublic)
словарь объекта
Получается что оба запрашивают страницу, при этом достаются из базы данных ZODB неявно публикуемые объекты,
они достают не явно не публикуемый объект авторизации. И уже этот объект у всех общий, вместе со своими членами. Почему, и как можно сделать, чтоб переменные такого объекта (словарь) был нужный для нужного пользователя.
Получается что если объект уже поднят из базы данных, то он уже общий у всех. А объект это и есть экземпляр класса.
Самое опасное, что словарь с данными для пользователя1 такой же, как и для пользователя2
Такого не происходит, если эти пользователи по очереди запрашивают страницу, а вот если запросили одновременно и выполнение параллельно, то получается что словарь (он же является членом класса AuthNonePublic, и представлен объектом AuthNonePublic )
для пользоваетля1 и пользователя2 одинаков.
Я это уидел по логированию содержимого словарей.
Почему такое происходит и как такое исправить?
Ну и извиняюсь, если я не очень корректно изьясняюсь.
то есть получается следующее - пользователь 1 зашёл на страницу, при этом очистился словарь авторизации и заполнился данными по пользователю1
в этот же момент заходить пользователь 2 и происходит то же самое, только уже с данными пользователя2.
и сразу после этого логируются данные со словаря по пользователю1 а там находятся данные от пользователя2.
Как можно избежать такого, чтоб данные объекта, поднятого для пользователя1 и инициализированные для него же, не модифицировались обслуживанием пользователя2
причём данная проблема характерна только для словарей. Если вместо словарей использовать переменные - то такой проблемы нет.
Отредактировано (Янв. 15, 2010 17:48:07)
Офлайн
Транзакции в ZODB нормально обрабатываются. Что за словарь? PersistentDict? Используйте BTree.
Разве есть информация о конфликте транзакций? В общем, нужно смотреть самому, так трудно понять, длинно.
PS. Пока есть время, могу брать проекты на сопровождение, на приемлемых условиях.
Офлайн
ситуация банальна
есть объект, есть вложенній объект. У вложенного объекта есть переменная и словарь (члены класса)
словарь - тот который a = {} ну и переменная, которая b = None
одновременно вызывается метод (тут я имею ввиду когда два разных пользователя вызвали одну и ту же страницу, где сначало вызывается метод для пользователя1 а потом этот же метод для пользователя2)
который делает простую вещь
self.a = ‘1’ - для первого пользователя
self.a = ‘2’ - для второго пользователя
и этот же метод делает
self.b = 1 - для первого пользователя
self.b = 2 - для второго пользователя
потом вызывается второй метод, который просто выводит в файл то, что находится в словаре a и переменной b
И оказывается, что в переменной b находятся значения 1 и 2 (для соответствующих пользователей)
а в словаре a - значение 2 для обоих пользователей.
Получается что словарь общий, и в нём находится значение, которое было установлено методом для пользователя 2
Ситуация невероятная, но вот такое я уже месяц наблюдаю, не хотел сюда писать, думал что где то ошибался в своих кодах. Кто нибудь знает как такое лечить, кроме как не использовать словари? Да и вообще, откуда такое берётся?
Отредактировано (Янв. 16, 2010 01:11:44)
Офлайн
А объект таки один на двоих, или это 2 разных объекта в базе, но одного класса ?
PS. Выше сказал уже, что нужно использовать PersistentDict или BTree. Обычный словарь нельзя использовать для сериализации.
from persistent.dict import PersistentDict
или
from BTrees.BTree import IOBTree, OOBTree & etc.
Офлайн
благодарен за совет, попробую. Класс точно один и тот же.
Сам объект создаётся вот так:
импорт
from auth_stat import AuthNonePublic
потом в ините
self.AuthNonePublic = AuthNonePublic(context, request)
если объект один на двоих - то почему тогда переменные разное значение имеют?
а если разный для каждого пользователя - то почему словари получаются общими?
А что происходит с обычным словарём, по какой причине он получается один на оба объекта? И почему этого не происходит с переменными?
Отредактировано (Янв. 16, 2010 10:16:22)
Офлайн
Ну, тут точно код смотреть надо. Иначе трудно понять, почему переменная имеет разное значение. Предполагаю, что это все таки не так, и собака зарыта где-то в коде адаптера вида или еще на каком-то уровне.
Иначе получается телепатия, сколько не описывай словами. Слова не нужны, нужен код, извиняюсь конечно.
Офлайн
ок, хотел убедится в типичности или не типичности такой беды. Если не нарою чего - буду пытаться словари перситстентные пользовать или BTree. На крайний случай - делать словарь вида словарь
тогда уже точно не будет такой путанници.
Отредактировано (Янв. 16, 2010 22:29:55)
Офлайн
misha111,
хотелось бы вдобавок к сказанному порекомендовать вам для прочтения следующее:
http://docs.zope.org/zodb/zodbguide/prog-zodb.html#writing-a-persistent-class
http://docs.zope.org/zodb/zodbguide/prog-zodb.html#rules-for-writing-persistent-classes
http://docs.zope.org/zodb/zodbguide/prog-zodb.html#modifying-mutable-objects
чтобы понять как работает персистентность в ZODB
или вообще весь гайд по ZODB; убъете полдня, зато не пожалеете.
astoon +1, склоняюсь к версии с ошибкой в адаптере.
Офлайн