[Seaside-dev] cookie based sessions, RESTful urls no _k

Nick Ager nick.ager at gmail.com
Fri Jan 27 14:05:33 UTC 2012


Hi,

In RESTful applications which also generate continuation key (_k) links a
problem can arise if you open multiple tabs all sharing the same session.
To illustrate:
1) Enable cookies for http://localhost:8080/examples/counter.
2) Open the counter and increment the value.
3) Open http://localhost:8080/examples/counter in a new tab and decrement
the counter.
4) Return to the first counter and increment the value - you will see "-1"
rather then "2" !

What I think is happening:
If Seaside finds a session but there is no continuation key (_k) then
WASession>>#handleFiltered: calls WARenderLoopMain>>#start which in turn
creates a new root presenter and calls #initialRequest on the
presenter. When the second tab is opened a new WACounter is created and
stored in the session's #presenter property. When you return to the first
tab, the callback is executed on the first counter, but the second counter
is rendered.

Ideas for possible fixes:

* I thought that #presenter was backtracked so don't understand why the
original counter #presenter isn't restored for the callback. If the
presenter was backtracked correctly then the counter example should work as
anticipated.... however:
* in Pier (and potentially other RESTful apps) you don't want to create a
new presenter for every RESTful call within an active session. If you don't
create a new presenter then #initialRequest currently won't be called,
which then won't allow your RESTful app to derive state from the url. If
Seaside is modified to call #initialRequest do you need to differentiate
between a call on a newly created session and one on an existing session?
You could differentiate with a call to a new method on WAPresenter, pass in
a flag to #initialRequest, or set a WARequestContext property to indicate a
new session had been created. What to do with backtracked state. Do you nil
all state before handling the request, restore state from a stored "initial
value" snapshot or just use the state of the components from their last
handled state?

I bought this issue up before [1], but didn't pursue it as I was struggling
to understand the issues and ran out of time. Julian responded to my
previous email when I was proposing a problematic fix with:

I'm not sure it's a good fix in the general case.  If you don't have a
> continuation key, you shouldn't (by definition) have any existing
> (backtracked) state. Relying on the root presenter currently in the
> Session is problematic since that value is backtracked for each
> request; you'll simply get whichever root happened to be used by
> whatever request was last handled by that session. If you don't happen
> to be ever changing the root, then it may well be what you want, but
> it's not right in the general case.
> Incidentally, this also touches on the flaw I was discussing the other
> week with our snapshots: because we have no continuation key, we
> really ought to nil out any backtracked data before processing the
> request (at least that way we have a consistent state while handling
> the request). We don't run into the problem with the root presenter
> because #start reinitializes it, but for other backtracked state,
> you'd just get random stuff in there based on the last-handled
> request.
> A more appropriate general fix (at least in this case) could be to
> take the last-used continuation and apply its state before handling a
> request with no _k. However, we don't always know the last-used
> (depending on the caching mechanism in place) and I'm not convinced
> that is actually always what people want. I still feel pretty
> confident that the "right" semantics of an Application/Session request
> with no _k is to start a new main/render-loop.


Certainly for Pier as it is currently designed I don't think that creating
a new render-loop for session requests with the _k is the right thing to
do, as it created a new root #presenter. I think ideally Seaside would for
existing session with no _k

1) Keep the existing #presenter
2) call #initialRequest with a flag to indicate that a new session hadn't
been created.
3) restore the state to an "initial render state" which is snapshotted (?)
when the initial render occurs on a new session.

Thoughts

Nick


[1]
http://forum.world.st/sessions-continuation-keys-restful-urls-and-component-state-td3532861.html









If each tabs starts with a RESTful url then a new presenter will be
created.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/seaside-dev/attachments/20120127/c2b08884/attachment.htm


More information about the seaside-dev mailing list