2

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 function to update and access and synchronize it. Coming from Java background! Any pointers?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Vishal
  • 19,879
  • 23
  • 80
  • 93
  • use the global declaration only, if there is no other way; it's usually a sign for a refactoring possiblity and i saw its usage in production code at most once. – miku Dec 18 '09 at 12:24
  • What do you mean by a "global dictionary"? How will this work when you site expands and requires multiple concurrent Django daemons? – S.Lott Dec 18 '09 at 13:04
  • possible duplicate of [What is the simplest way to lock an object in Django](http://stackoverflow.com/questions/698950/what-is-the-simplest-way-to-lock-an-object-in-django) – Pace May 22 '14 at 15:45

2 Answers2

2

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
  • 4,479
  • 1
  • 21
  • 20
1

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
  • 99,910
  • 10
  • 151
  • 209