Hi, I'm trying to set and then read a session variable on the same request. Basically, I have a script which sets a session variable when called, and then redirects back to a content item. That item's __bobo_traverse__ then looks for this variable. Trouble is, the variable I'm setting doesn't seem to be present when I check it. My 'setter' script looks like this: if response == '1': context.REQUEST.SESSION['secure_acknowledge'] = 1 context.REQUEST.RESPONSE.redirect(site.absolute_url()) The relevant lines in the site __bobo_traverse__ are: response = self.REQUEST.RESPONSE if not self.REQUEST.SESSION.has_key('secure_acknowledge'): zLOG.LOG(__name__, 0, "no ack") cr = self.portal_url.getPortalObject()[CONTENT_ROOT_NAME] response.redirect(cr.absolute_url() + '/secure_site_notice?came_from=%s' % self.UID()) else: zLOG.LOG(__name__, 0, "ack") ... I always end up with 'no ack' in my log. If I dump the contents of the SESSION just after the variable is set, then I can see it - but it's gone by the time I actually want to process it! What am I doing wrong? Cheers, Dan
Zope sessioning data is transactional. You are setting a session variable in one database connection, and presumably before the transaction that involves that connection has a chance to commit, you are telling the browser to redirect, which has the behavior of opening a separate connection which may or may not see the changes committed by the first connection to the database. This is actually a race condition. It might even work sometimes but it's dependent on outside factors. Arguably, there's no good reason to use __bobo_traverse__ unless you're trying to make non-ZODB objects appear as if they were traversable (it doesnt appear from your example that you're doing that). Ditch __bobo_traverse__ and move the send-this-guy-to-a-different-page logic into a script or template. And then instead of redirecting to the content object in the if response == "1" stanza, "return content_object.script_or_template_name()", which should then do the right thing. BTW, I fully expect you to say that this won't work for you. I can sympathize but going down the road of telling the initial connection to commit explicitly is possible but fraught with peril. It's so perilous that I need to refuse on moral grounds to even explain how to do it! ;-) - C On Mon, 2004-09-13 at 14:00, Dan Fairs wrote:
Hi,
I'm trying to set and then read a session variable on the same request. Basically, I have a script which sets a session variable when called, and then redirects back to a content item. That item's __bobo_traverse__ then looks for this variable.
Trouble is, the variable I'm setting doesn't seem to be present when I check it.
My 'setter' script looks like this:
if response == '1': context.REQUEST.SESSION['secure_acknowledge'] = 1 context.REQUEST.RESPONSE.redirect(site.absolute_url())
The relevant lines in the site __bobo_traverse__ are: response = self.REQUEST.RESPONSE if not self.REQUEST.SESSION.has_key('secure_acknowledge'): zLOG.LOG(__name__, 0, "no ack") cr = self.portal_url.getPortalObject()[CONTENT_ROOT_NAME] response.redirect(cr.absolute_url() + '/secure_site_notice?came_from=%s' % self.UID()) else: zLOG.LOG(__name__, 0, "ack")
... I always end up with 'no ack' in my log.
If I dump the contents of the SESSION just after the variable is set, then I can see it - but it's gone by the time I actually want to process it!
What am I doing wrong?
Cheers, Dan
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Hi,
BTW, I fully expect you to say that this won't work for you. I can sympathize but going down the road of telling the initial connection to commit explicitly is possible but fraught with peril. It's so perilous that I need to refuse on moral grounds to even explain how to do it! ;-)
Don't worry, I naively tried it once before. I've only just regained my sanity! :) Thanks for the comments, I did suspect it would be to do with the transactional nature of the session data - I just wanted to check that I wasn't making a silly mistake (as is usually the case!) Cheers, Dan
Chris McDonough wrote at 2004-9-13 14:18 -0400:
Zope sessioning data is transactional. You are setting a session variable in one database connection, and presumably before the transaction that involves that connection has a chance to commit, you are telling the browser to redirect,
I do not believe this: For normal requests (such that do not use "RESPONSE.write"), the response is delivered to the client only after the transaction has been committed. -- Dieter
On Tue, 2004-09-14 at 15:48, Dieter Maurer wrote:
Chris McDonough wrote at 2004-9-13 14:18 -0400:
Zope sessioning data is transactional. You are setting a session variable in one database connection, and presumably before the transaction that involves that connection has a chance to commit, you are telling the browser to redirect,
I do not believe this:
For normal requests (such that do not use "RESPONSE.write"), the response is delivered to the client only after the transaction has been committed.
You're right of course, thanks. Then I have no good explanation. The only other explanation I could conceive of is that the redirect happens even if the page that sent it raised an error (which would abort the transaction instead of committing it). I wonder if this can happen with some tortured use of the lock=1 parameter to RESPONSE.redirect. - C
Chris McDonough wrote at 2004-9-14 21:40 -0400:
... session info lost after redirect ... The only other explanation I could conceive of is that the redirect happens even if the page that sent it raised an error (which would abort the transaction instead of committing it). I wonder if this can happen with some tortured use of the lock=1 parameter to RESPONSE.redirect.
It probably would be possible with "lock=1" but I doubt that the poster used it (it is hidden quite well). -- Dieter
participants (3)
-
Chris McDonough -
Dan Fairs -
Dieter Maurer