Graham Dumpleton
grahamd at dscpl.com.au
Sun Mar 27 19:31:00 EST 2005
Scott, did you work this out yet? I had a little play with it, although I had to change your code first as what you posted didn't even work. Needed to use code: def respond(self): self.req.log_error('Responding ' + self.req.uri) #methodName=self.req.uri[:len(self.req.uri)- len(self.req.path_info)][1:] methodName=self.req.uri[len(self.req.uri)-len(self.req.path_info):][1:] self.req.log_error('methodName: '+methodName) if methodName == 'index': #self.internal_redirect('/login') prefix=self.req.uri[:len(self.req.uri)-len(self.req.path_info)] self.req.log_error('Redirecting to login '+prefix+'/login') self.internal_redirect(prefix+'/login') if methodName == 'login': self.req.log_error('Doing login') self.writeln ('<h1>login_here</h1>') return True This may partly be because I wasn't doing it in document root. Anyway, after some digging found that adding "self.session.unlock()" will fix the problem but it has to be in the mpservlets Servlet class. Thus, it may well be a issue that Daniel (author of mpservlets) may need to look at. The change in mpservlets is: def __cleanup_session(self): if self.use_session and self.session is not None: self.session.save() self.session.unlock() self.session = None Ie., add call to unlock() just after saving the session. Normally this unlock() would be called, but only when the Session object itself is deleted or by way of a cleanup function registered against the request using req.register_cleanup(). The problem is that even though one sets self.session to None, this doesn't mean it will be deleted immediately as one is in part at the mercy of the Python garbage collector. That it isn't unlocked may actually keep it alive longer and normally it may only be unlocked by request cleanup function at which point it then gets destroyed. Unfortunately, because your internal redirect loops back onto the same servlet, the second time through it tries to lock the same session, but where the prior hasn't been unlocked yet. Thus deadlock as lock is not reentrant for same thread. Thus, believe mpservlet possibly needs to be fixed, but might also question your design anyway, there possibly being better ways of achieving what you want. You might want to explain to the list what you are wanting to achieve and you might get some helpful suggestions back. Graham On 27/03/2005, at 8:41 AM, Scott Chapman wrote: > > My previous post didn't address the issue correctly. > I made some error logging in mpservlets to see where things stop. In > this case, the internal redirect is not being called. It never gets > that far: > [Sat Mar 26 14:34:02 2005] [error] [client 192.168.1.127] HANDLER - > calling auth > [Sat Mar 26 14:34:02 2005] [error] [client 192.168.1.127] HANDLER - > calling prep > [Sat Mar 26 14:34:02 2005] [error] [client 192.168.1.127] PREP - > clearing self.__out > [Sat Mar 26 14:34:02 2005] [error] [client 192.168.1.127] PREP - > setting self.form > [Sat Mar 26 14:34:02 2005] [error] [client 192.168.1.127] PREP - > calling __load_vars() > [Sat Mar 26 14:34:02 2005] [error] [client 192.168.1.127] PREP - > setting self.session > > -- end of log -- > > We never see "Redirecting to login" in the log. > > So, the initial establishment of the session is failing, due to > locking. > > I have no idea why. > > Scott > > > Graham Dumpleton wrote: > >> Try adding: >> >> self.session.unlock() >> >> just before the internal redirect and see what happens. >> >> I don't believe this should be required as mpservlets is using >> its own internal redirect which actually saves the session before >> doing the real internal redirect. >> >> Anyway, this "experiment" might at least help you to understand >> things better. >> >> BTW, I am assuming when you say "make session lock=0", you mean >> setting "use_session" appropriately. Is that correct? >> >> Graham >> >> On 27/03/2005, at 7:29 AM, Scott Chapman wrote: >> >>> Using linux - prefork mpm. >>> I set my httpd.conf: >>> StartServers 1 >>> MinSpareServers 1 >>> MaxSpareServers 0 >>> MaxClients 1 >>> MaxRequestsPerChild 0 >>> >>> for this test run. >>> >>> Here's my UberServlet: >>> -------------- snip -------------- >>> from mod_python.servlet import Servlet >>> >>> class uberservlet(Servlet): >>> use_session = True >>> >>> def respond(self): >>> self.req.log_error('Responding') >>> methodName=self.req.uri[:len(self.req.uri)- >>> len(self.req.path_info)][1:] >>> self.req.log_error('methodName: '+methodName) >>> if methodName == 'index': >>> self.req.log_error('Redirecting to login') >>> self.internal_redirect('/login') >>> if methodName == 'login': >>> self.req.log_error('Doing login') >>> self.writeln ('<h1>login_here</h1>') >>> return True >>> >>> def wrapup(self): >>> Servlet.wrapup(self) >>> -------------- snip -------------- >>> When I make Sesssion lock=0, it doesn't hang. >>> When I don't set lock = 0 (the default) it hangs when trying to >>> establish the session: >>> self.session = Session.Session(self.req, >>> timeout=self.session_timeout) >>> >>> What problems do I look forward to if I run with lock=0? >>> >>> Quoting Grisha: >>> "One thing you may try as an experiment is to disable session locking >>> (Session(lock=0)). It will still use locking for access to the DBM, >>> but it won't lock individual sessions." >>> >>> Grisha calls this "an experiment". Can anyone tell me why locking >>> is failing and what will happen if I run with locking off? >>> >>> TIA, >>> Scott >>> _______________________________________________ >>> Mod_python mailing list >>> Mod_python at modpython.org >>> http://mailman.modpython.org/mailman/listinfo/mod_python >> >> >> >>
|