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

Philippe Marschall philippe.marschall at gmail.com
Sun Jan 29 19:21:56 UTC 2012


2012/1/27 Nick Ager <nick.ager at gmail.com>:
> 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

I know this is a loaded topic but what about Pier subclasses WASession
to get the behavior it needs?

Cheers
Philippe


More information about the seaside-dev mailing list