[ZODB-Dev] Webkit Threading and ZODB 3.3a2: problems on Windows
Matt Feifarek
matt at dalchemy.com
Wed Feb 18 13:41:57 EST 2004
Hello.
We've run into an interesting problem using ZODB 3.3a2 and Webware
Webkit's threaded application server (http://webware.sourceforge.net) on
Windows (but not Linux).
The symptom that alerted us to the problem was that object attributes
sometimes -- but inconsistently -- failed to be persisted. (No, this
problem has nothing to do with mutables. Yes, we're sure.)
First (for the ZODB people), a quick summary of how the Webkit
application server works: the server maintains a pool of threads to
service URI requests. Each request is assigned an available, running
thread. The app server does one of two things:
1) instantiates a new servlet instance and passes the request to be serviced
- or -
2) it finds an already-running instance of the relevant servlet and
passes it
the request to be serviced
In either case, these threads eventually return a response string to the
http client.
The crucial subtlety is that a thread does NOT destroy/garbage-collect
its servlet instance after servicing the request. Rather, the servlet
instance is "put to sleep" and kept around in case another request is
for the same servlet. If the application is taking requests for many
different servlets, the servlet instances do slip in and out of the pool
as different requests come in, but there is no guarantee that a servlet
instance will be brand new with every request.
The crux: it appears that Webkit's threading model exposes a ZODB
problem when a Webkit servlet transacts with a ZODB under Windows.
Changes to persistent objects are made and committed within servlet
code. If you watch the _p_changed attribute before and after running
get_transaction().commit(), we assume it should always be 1 before the
commit() and 0 after the commit. Under our Windows test case, sometimes
_p_changed is 1 following the commit() suggesting that get_transaction()
somehow isn't getting the right transaction, and therefore nothing is
actually being committed after all. The exact same Webkit code does not
exhibit this problem running under Linux.
We have identified to workarounds on Windows:
1) limit the Webkit app server to one thread; this solves the problem
but neatly renders the app server useless for production purposes
2) add a seemingly superfluous get_transaction().abort() call just
before the servlet is put to sleep (and before the database connection
is closed) by the app server; apparently, if you make this call (even
when you've made no changes) a side effect is precluding whatever
circumstances are leading to the real problem
Here are some more details on what we've tested:
Windows:
- python 2.3.3
- ZODB 3.3a2 using standard FileStorage with BTrees
- NOT using ZEO
- Webware 0.8
Linux:
- python 2.3.1
- ZODB 3.3a2 using standard FileStorage with BTrees
- NOT using ZEO
- Webware 0.8
We also noticed that the object returned by get_transaction() has an
_id. If we watch this value as servlets transact with ZODB, we've
noticed that the ids are frequently re-used. Perhaps this is relevant?
If anyone would like more information on tracking down this bug, we'd
love to help. We're afraid that we're probably near the limits of our
expertise, but can help with debug print statement output or whatever.
Thanks!
More information about the ZODB-Dev
mailing list