bje at apnic.net
Fri Aug 13 10:17:07 EDT 2004
Amir Salihefendic wrote: > I welcome myself to this list ;-) Welcome! [working example] > def createSession(req): > def getSameSession(req): The important thing to note here is that the code is identical in both calls. That is, if you call Session.Session(req) with no session ID in cookies, or the existing session ID has no matching session stored on disk, a new session ID is generated. But, the session is /not/ written to disk. > def createSession(req): > return getSameSession(req) > def getSameSession(req): > return same_session.id() So when you change to calling getSameSession() from createSession() you are in fact creating /two/ sessions. My guess would be that your apparent infinite loop is in fact a deadlock, caused by the fact that your second created session will be reusing the session ID created by the first one, and then attempting to establish a global lock on that session ID. Bad. > This does not work - it makes an infinitive loop..! Now to fix this you > need to unlock the session in createSession (.. I have no clue why you > have to do this..?). And then you need to restart apache... i.e.: This bears up my analysis well. The locking done by the Session module is an Apache-wide lock on the session ID. So, when createSession() first creates a session, it locks that sid. Then, it calls getSameSession() which attempts to lock the same sid. The lock call blocks here, waiting for the first lock to be released, but that release will never come. If you cause the first created session to unlock itself, you will not create a deadlock, but you will need to restart apache to break an existing deadlock. > But this does not work quite well.. If you delete the Session: > And then you do this: > First time the id's aren't same - after that they are the same. When a session has been deleted, it is marked as invalid and calling .load() on that sid will fail. .__init__() will create a new sid if .load() fails for an existing one, so I suspect you are seeing this behaviour. Overall, it seems you are making the session management process far more complicated than it needs to be. Under what circumstances do you call createSession() instead of getSameSession() ? I am successfully using the Session module to handle an HTML forms based login system: session = Session.Session(req) if NeedAuth and not session.has_key('username'): redirect(AuthPage) ServePage(req) session.save() return apache.OK This is a simplification, since I use an extensible application object that allows you to change how sessions are generated and how users are authenticated, but it boils down to the above. I create a new session or get an existing session. I do not care which. If the page being requested needs auth, but the session doesn't contain a username key, I redirect to the login page, which stores the username value into the session if the user presents the right credentials. Otherwise, I serve the requested page, then save the session, and Bob's a builder. Note that I cannot distinguish between an expired session and no session at all, but this is a limitation of the Session module. I can distinguish between a new session and an existing session by calling session.is_new(), but that distinction turns out not to be very important. At some point, I will need to extract the sid from the cookie set myself, to be able to distinguish between a timed out session, an invalidated session, a missing session and a brand new session. (Or else I'll have to patch the Session module, which I'm not real keen to do.) -- bje  The 'redirects' I do are simply changing what view my code believes it is processing, so execution continues down the line, and session.save() is called in due order. If you're using an Apache internal redirect or a 302/303 redirect, you should ensure new sessions are saved as soon as created with "if session.is_new(): session.save()".