On Mon, 2002-08-19 at 17:45, Matt Feifarek wrote:
> | Well, most of the time we just put persistent values in module-level
> | globals (remembering to do proper locking via threading.Lock, and often
> | using dictionaries to organize the data).
>
> Can you elaborate on that threading.lock bit a little? We use a similar
> technique, and don't mess with threading.
It's not always necessary to use locks, but everything in Webware has to
be threadsafe -- servlets are run in their own threads, and those
threads can simultaneously access the same function or method. More
specifically, you have to be careful with writing to global resources
(module-level variables, class variables, etc). Threading bugs will
often only arise under heavy usage, and are a pain to debug, so it's
worth being careful.
For an example, I use a factory pattern that create an object based on
an ID, but if the object by that ID already exists then that object is
recycled. Actually, instead of giving pseudocode, I'll just list that
factory, which uses locks. It would work without locks, but it could
not ensure that there would never be two objects from the same ID.
(Actually, instead of ID, it uses a tuple of arguments to the
constructor, but in practice I only use a single integer ID)
from threading import Lock
class ParamFactory:
def __init__(self, klass):
self._lock = Lock()
self._cache = {}
self._klass = klass
def __call__(self, *args):
self._lock.acquire()
if not self._cache.has_key(args):
value = self._klass(*args)
self._cache[args] = value
self._lock.release()
return value
else:
self._lock.release()
return self._cache[args]
Only in a very specific, and fairly unlikely situation would this lock
be necessary. Say you do something like:
# setup...
class _User:
def __init__(self, userID):
...
# User is my faux-class, actually a factory
User = ParamFactory(_User)
# thread 1 does:
u = User(userID)
# thread 2 does the same thing:
u2 = User(userID)
If both threads are executing this instruction at once, and thread 1
gets to the "if not self._cache.has_key(args)", but hasn't finished
"self._cache[args] = value" before thread 2 gets to that same if
statement, then two instances of the object will be created. As you
might expect, this might only happen one time in a million. Or it may
only occur under some specific and (at least initially) unusual
circumstance. But other kinds of global-writes can cause these race
conditions quite often.
Ian
-------------------------------------------------------
This sf.net email is sponsored by: OSDN - Tired of that same old
cell phone? Get a new here for FREE!
https://www.inphonic.com/r.asp?r=sourceforge1&refcode1=vs3390
_______________________________________________
Webware-discuss mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/webware-discuss