Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 15, 2010 14:54:49

misha111
От:
Зарегистрирован: 2009-11-12
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

Всем здравствуйте. Может кто сталктвался с данной проблемой и подскажет как решать?
Проблема следующая (возможно реализция покажется кому то не правильной. но что есть то есть)

Есть проект, в котором описаны публикуемые классы и не публикуемые. (объекты этих классов, насколько я понимаю, находятся в 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)

Офлайн

#2 Янв. 15, 2010 21:41:44

astoon
От:
Зарегистрирован: 2007-04-09
Сообщения: 335
Репутация: +  2  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

Транзакции в ZODB нормально обрабатываются. Что за словарь? PersistentDict? Используйте BTree.
Разве есть информация о конфликте транзакций? В общем, нужно смотреть самому, так трудно понять, длинно.

PS. Пока есть время, могу брать проекты на сопровождение, на приемлемых условиях.



Офлайн

#3 Янв. 16, 2010 01:09:12

misha111
От:
Зарегистрирован: 2009-11-12
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

ситуация банальна
есть объект, есть вложенній объект. У вложенного объекта есть переменная и словарь (члены класса)
словарь - тот который 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)

Офлайн

#4 Янв. 16, 2010 05:22:29

astoon
От:
Зарегистрирован: 2007-04-09
Сообщения: 335
Репутация: +  2  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

А объект таки один на двоих, или это 2 разных объекта в базе, но одного класса ?

PS. Выше сказал уже, что нужно использовать PersistentDict или BTree. Обычный словарь нельзя использовать для сериализации.

from persistent.dict import PersistentDict
или
from BTrees.BTree import IOBTree, OOBTree & etc.



Офлайн

#5 Янв. 16, 2010 10:10:36

misha111
От:
Зарегистрирован: 2009-11-12
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

благодарен за совет, попробую. Класс точно один и тот же.
Сам объект создаётся вот так:
импорт
from auth_stat import AuthNonePublic
потом в ините
self.AuthNonePublic = AuthNonePublic(context, request)
если объект один на двоих - то почему тогда переменные разное значение имеют?
а если разный для каждого пользователя - то почему словари получаются общими?

А что происходит с обычным словарём, по какой причине он получается один на оба объекта? И почему этого не происходит с переменными?



Отредактировано (Янв. 16, 2010 10:16:22)

Офлайн

#6 Янв. 16, 2010 16:09:52

astoon
От:
Зарегистрирован: 2007-04-09
Сообщения: 335
Репутация: +  2  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

Ну, тут точно код смотреть надо. Иначе трудно понять, почему переменная имеет разное значение. Предполагаю, что это все таки не так, и собака зарыта где-то в коде адаптера вида или еще на каком-то уровне.

Иначе получается телепатия, сколько не описывай словами. Слова не нужны, нужен код, извиняюсь конечно.



Офлайн

#7 Янв. 16, 2010 22:29:35

misha111
От:
Зарегистрирован: 2009-11-12
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

ок, хотел убедится в типичности или не типичности такой беды. Если не нарою чего - буду пытаться словари перситстентные пользовать или BTree. На крайний случай - делать словарь вида словарь
тогда уже точно не будет такой путанници.



Отредактировано (Янв. 16, 2010 22:29:55)

Офлайн

#8 Янв. 17, 2010 12:43:37

regall
От: Киев
Зарегистрирован: 2008-07-17
Сообщения: 1583
Репутация: +  3  -
Профиль   Отправить e-mail  

проблема про общие словари в многопоточной работе

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, склоняюсь к версии с ошибкой в адаптере.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version