tags:

views:

25

answers:

1

Hi,

A module level dictionary 'd' and is accessed by different threads/requests in a django web application. I need to update 'd' every minute with a new data and the process takes about 5 seconds.

What could be best solution where I want the users to get either the old value or the new value of d and nothing in between.

I can think of a solution where a temp dictionary is constructed with a new data and assigned to 'd' but not sure how this works!

Appreciate your ideas.

Thanks

+2  A: 

Probably best -- at module level:

import threading
dlock = threading.Lock()
d = {}

and every access to d (not just modifications!) is within a with block:

with dlock:
    found = k in d

and the like (if you're on Python 2.5, you'll also need to have from __future__ import with_statement at the top of your module).

This protects d with the lock, so changes are serialized. The reason the guard is also needed around non-modifying access to d is that you might otherwise get problems even in "read-like" operations (if k in d:, d.get(k), etc) if the dict gets "changed from right under the operation smack in the middle of it".

Alternative architectures can be based on wrapping the dictionary (either to protect all of its needed methods with the lock, or to delegate a special purpose thread to perform all the dictionary operations and communicate with all other threads via Queue.Queue instances), but I think that in this particular case the simple, no-frills solution works for the best.

Alex Martelli
Do users have to wait when d is being modified or they can still get the old value of d.
Vishal
Alex Martelli
@Alex, What if updating d is taking a few seconds then threads will be waiting to get the lock? or did you mean assigning temp to d as in the question?
Vishal
@Vishal, how can updating a dict take **seconds**?! `d[k]=v` takes 150 nanoseconds on my dated, slow laptop -- even "a few microseconds" would require a thousand threads all waiting to update (so many thousands overall, since surely they're not all updating). I explained that the "assigning temp to d" approach **will** completely lose updates -- if 1000 threads "work at once" on the dict, up to 999 of their updates can simply vanish into thin air.
Alex Martelli
@Alex, Assignment isn't the problem but it takes seconds because I read data from the network and construct d. Also in "temp to d" approach only one thread will update and rest all just read.
Vishal
@Vishal, each thread obviously must do all the time-consuming work on its own and only get the lock and update the dict when everything is ready, "in one fell swoop". Serializing only writers (and starting or ending each write-under-lock by a deepcopy of the dict) is possible but iffy.
Alex Martelli
@Alex, I got it thanks :)
Vishal