dharana wrote:
OFFENDING CODE
handler's code:
from mod_python import Session, apache
from ozone.storage.Storable import Storable
from ozone.websites.Website import Website
from ozone.websites.DynamicWebsite import DynamicWebsite
def handler(req):
req.sess = Session.FileSession(req)
req.sess['storable'] = Storable()
req.sess['website'] = Website()
req.sess['dynwebsite'] = DynamicWebsite()
req.sess.save()
req.write('session_id: %s' % req.sess.id())
return apache.OK
RESULT:
(see below)
COMMENT:
DynamicWebsite inherits from both Storable and Website as I told in a
previous email. I create three instances and I save them in the session.
---------------
CONTENTS OF ozone.websites.DynamicWebsite
CASE A
from ozone.storage.Storable import Storable
from ozone.websites.Website import Website
class DynamicWebsite(Storable, Website):
pass
RESULTS:
No segfault. No new session is created on each request, all three
instances are saved and retrieved correctly. It seems to work Ok.
--------------------------------------------------
CASE B
from ozone.storage.Storable import Storable
from ozone.websites.Website import Website
class DynamicWebsite(Storable, Website):
_dbschema = 'o3_websites'
I wonder if _dbschema, which is a class attribute, is the problem?
Quoting from the python documentation for pickle
(http://www.python.org/doc/2.3.5/lib/node65.html)
"""Similarly, classes are pickled by named reference, so the same
restrictions in the unpickling environment apply. Note that none of the
class's code or data is pickled, so in the following example the class
attribute attr is not restored in the unpickling environment:
class Foo:
attr = 'a class attr'
picklestring = pickle.dumps(Foo)
"""
I haven't tried any tests within mod_python, but its a good place to start.
Regards,
Jim
RESULTS:
[notice] child pid 1695 exit signal Segmentation fault (11)
COMMENT:
Storable's __init__ calls another function that uses the _dbschema
attribute to call another function and to populate the object's
attributes. Althought it's weird (imo) that this could cause a segfault,
it's weirder because the User object (class User(Storable)) _works_
correctly if I store it in session and it does exactly the same thing.
I hope to have made it as clear as possible. This is really weird.
Nicolas Lehuen wrote:
Hi dharana, I have a two parts answer :
1) One thing I'm really sure is that there is no way for the pickle
module to handle the request object correctly. Hence, if the session
code is trying to pickle an object which contains a reference to a
request object, I have no idea of how this can be done. This is
another possible explanation of the segfault. Maybe you could try to
pickle then reload an object with a reference to the request object,
like this :
import cPickle
def index(req):
d = { "request" : req }
test1 = cPickle.loads(cPickle.dumps(d))
return str(test1)
In any case, storing an object with a reference to the request in a
session is not a godd thing to do ; a request is a transient object,
which is not meant to live for more than the request's processing
time.
3) Another possible problem with loading pickled sessions is the case
where you are trying to load some user-defined class instances.
Due to the way pickling works, the class of an instance is saved by
name, and the unpickling code automagically reimports the module of
the class and rebuild the instance from there.
When the class is defined in a published module (and this is also true
for mod_python 3.1.4 and before), I can't see how the unpickling code
can possibly find the proper published module, since the standard
importing mechanism won't find the published module. This should raise
a nice Python exception, but maybe with cPickle or in certain
circumstances this causes a segmentation fault.
To rule out this problem I would try to define the object class in a
module that could be found on the PythonPath, rather than directly in
the published module.
3) Uh oh. If you're suspecting that this problem is related to
circular dependencies with the request object, then maybe this bug is
caused by the changes I've made to support the garbage collection of
the request object, since I had to implement some traversal code that
could fail for a reason or another.
Would it be possible for you to perform the same tests with the 3.1.4
version of mod_python.so ? We would make clear whether this is due to
something like that.
Tell us if your experimentations gives some results ; I'll have a look
at this but it is much too late for me now.
Regards,
Nicolas
2005/5/24, dharana <[EMAIL PROTECTED]>:
Hi Jim,
Objects of types int, str, unicode, etc don't cause a segfault.
Currently I'm
storing just a string and an User object of mine. It segfaults when an
undetermined ammount of time passes (it may be around 30 mins). It
happens even
if I'm continually browsing not just staring at the screen and it
happens almost
always.
If I try to store a DynamicWebsite object it segfaults every time and
at that
moment, no need to wait some minutes.
Background info:
class User(Storable):
# one single method which calls another custom function in another
module of
mine plus the inherited methods
class DynamicWebsite(Website, Storable):
# a more complex object. The base class Website assigns req to
self.req. This
child class modifies it in one of it's three methods. Perhaps has
something to
do? It also import custom modules from some of it's functions.
class Storable(object):
# just an interface to load/save from a db
I will be a bit busy until saturday. I will try to make a testcase
then, but
it's not trivial.
Perhaps it has to do with circular dependencies with the req object?
Please look at my comment here:
http://issues.apache.org/jira/browse/MODPYTHON-45
I can't see wether this has anything to do with the problem at hand
but just in
case.
Jim Gallacher wrote:
Hi dharana,
I've been away for a few days, but should have some time to mess around
with this today.
--
dharana