tags:

views:

98

answers:

3

In django when updating a global dictionary data structure I want to lock access to it by different request. I am planning to have a wrapper funtion to update and access and synchronize it. Coming from java background! Any pointers?

A: 

Best answered in this question.

Pace
+1  A: 

One fun option is to create a Lockable DIctionary class that will lock itself based on teh exection frame of the caller. :-)

Python introspection allows this - and depending on you r needs, this might fit - (you would have to catch the exception raised in the places you want to use the valu, though -- I don' t use Django, so I don't know if the rewquests use threads -- if so, (and not asynchronous response over a single thread for all requests), you can replace the Exception raised for a while - sleep - retry loop.

from inspect import stack

class DictLocked(Exception):
    pass

class LockableDict(dict):
    def __init__(self, *args, **kw):
        dict.__init__(self, *args, **kw)
        self.locked = False
        self.locker = None
    def start_update(self):
        print stack()
        self.locked = True
        #Holds the code frame responsible for locking
        self.locker = stack()[1][0]
    def finish_update(self):
        self.locked = False

    def __getitem__(self, item):
        print stack()
        if self.locked:
            if stack()[1][0] != self.locker:
                raise DictLocked("Dictionary locked")
        return dict.__getitem__(self, item)

    def __setitem__(self, item, value):
        if self.locked:
            if stack()[1][0] != self.locker:
                raise DictLocked("Dictionary locked")
        return dict.__setitem__(self, item, value)
jsbueno
+1  A: 

Extending the LockableDict example somewhat, to make it a little more robust you can use the real Lock:

class LockableDict(dict):
    def __init__(self, *args, **kwargs):
        from threading import Lock
        self.lock = Lock()
        dict.__init__(self, *args, **kwargs)

    @property
    def locked(self):
        return self.lock.locked()

    def lock(self):
        self.lock.acquire()

    def unlock(self):
        self.lock.release()

# and then
my_dict = LockableDict({1:2, 3:4})
my_dict.lock()
# do modifications
my_dict.unlock()
kibitzer
Thanks, just that the lock name is common for the function and the variable! rest worked great
Vishal
yes sorry about that, better call the attribute __lock to make it ptivate
kibitzer