cookie based sessions, RESTful urls no _k

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

cookie based sessions, RESTful urls no _k

Nick
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











If each tabs starts with a RESTful url then a new presenter will be created. 

_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: cookie based sessions, RESTful urls no _k

Philippe Marschall
2012/1/27 Nick Ager <[hidden email]>:

> 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
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: cookie based sessions, RESTful urls no _k

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

a subclass of WASession may solve the problem for Pier, though it would suffer from other problems; composability etc.

However, the point I tried to make above is that this is a general Seaside problem - not specific to Pier, though Pier as a RESTful application exposes the issue.

_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: cookie based sessions, RESTful urls no _k

Philippe Marschall
2012/1/31 Nick Ager <[hidden email]>:
>> I know this is a loaded topic but what about Pier subclasses WASession
>> to get the behavior it needs?
>
>
> a subclass of WASession may solve the problem for Pier, though it would
> suffer from other problems; composability etc.

You know it's the 10s when everybody hates inheritance :-(

> However, the point I tried to make above is that this is a general Seaside
> problem - not specific to Pier, though Pier as a RESTful application exposes
> the issue.

Right. But my understanding is that from what Julian said there is no
generic fix because if you don't have a RESTful (probably the wrong
word) URL then the current behavior is correct. To me the problem
seems to be that we hack all these things into #initialRequest:
because that's the only real way we have of dealing with state in the
URL. To me the question is whether instead of putting another brittle
hack into WASession we should rather move things that don't really
need a session into a filter on session or application and have a
better way to initialize components from state from the request URL.
In general better support for applications that have state in the URL.
This kinda goes in the way of the "Window shopping mode" that David
Buck was talking about. A generic way of going form a session less
application to a session based application. You recently said you
wanted vision, there it is :-)

Cheers
Philippe
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: cookie based sessions, RESTful urls no _k

Julian Fitzell-2
On Tue, Jan 31, 2012 at 8:14 PM, Philippe Marschall <[hidden email]> wrote:
2012/1/31 Nick Ager <[hidden email]>:
> However, the point I tried to make above is that this is a general Seaside
> problem - not specific to Pier, though Pier as a RESTful application exposes
> the issue.

Right. But my understanding is that from what Julian said there is no
generic fix because if you don't have a RESTful (probably the wrong
word) URL then the current behavior is correct. To me the problem
seems to be that we hack all these things into #initialRequest:
because that's the only real way we have of dealing with state in the
URL. To me the question is whether instead of putting another brittle
hack into WASession we should rather move things that don't really
need a session into a filter on session or application and have a
better way to initialize components from state from the request URL.
In general better support for applications that have state in the URL.
This kinda goes in the way of the "Window shopping mode" that David
Buck was talking about. A generic way of going form a session less
application to a session based application. You recently said you
wanted vision, there it is :-)

I've been playing this week again with pulling the concept of a session (i.e. what the rest of the world calls a session) up outside the level of the Application. This means you could wrap the entire site (or a particular Dispatcher) in a session filter that would make the session available to everything below it. This seems to work pretty well (need to sort out how to deal with query-parameter-based session keys, but works fine with cookies...) and seems like it ought to make such a transition easier.

Still experimenting with ideas... (that's only one of many on the go in this image)

Julian


_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev