Multiple Instances of the Same Page and Persistence

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Multiple Instances of the Same Page and Persistence

Patrick Casey

        I'm having a bit of a problem with a manually persisted property.

        I have a list of users.
        If somebody selects one user, I bring up an edit form and persist a
key value.
        If the user presses save, the edit form object uses the persisted
key to reload the object before pushing the user's edits in.

        It works fine, but only if there's only *one* edit page up. Example:

        I have a list of users.
        User pressed "open in new tab" on John Smith -> persist key #43
        User pressed "open in new tab" on Jane Doe -> persist key #86 //
doh!
        User now changes John Smith's data on the form and presses save.
       
        The currently persisted key for the edit form though is 86, not 43,
so we end up overwriting Jane Doe's information instead of updating John
Smith's information.

        I've resolved this problem by not using the Tapestry persistence
layer and instead stuffing the key into a hidden field on the form, but it
strikes me there has to be a way to make it work and still use the
persistence layer.

        Can anyone offer some advice here? Is this just a case where I can't
use Tapestry persistence?

        --- Pat



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multiple Instances of the Same Page and Persistence

Bryan Lewis
I don't have an answer for you, but I came across a similar problem a few
days ago with Firefox.  I assume it's Firefox since you mentioned opening a
new tab.

When I access our site I get auto-logged-in with a cookie and get a new
session as expected.  If I open a new tab and repeat the same URL, I get
another view onto the *same* session.  No new login.  I can easily reproduce
the nasty behavior you're seeing, without being as tricky as right-clicking
a link to open it in a new tab.

In fact if I start another instance of Firefox (a new browser window, not a
tab) the same thing happens.  Doing this in IE starts a new session.  I've
done a little googling and found another user complaining about this but no
quick fixes.  Hoping someone else in this list has some expeirence with
this.


----- Original Message -----
From: "Patrick Casey" <[hidden email]>
To: "'Tapestry users'" <[hidden email]>
Sent: Saturday, May 07, 2005 2:47 PM
Subject: Multiple Instances of the Same Page and Persistence


>
> I'm having a bit of a problem with a manually persisted property.
>
> I have a list of users.
> If somebody selects one user, I bring up an edit form and persist a
> key value.
> If the user presses save, the edit form object uses the persisted
> key to reload the object before pushing the user's edits in.
>
> It works fine, but only if there's only *one* edit page up. Example:
>
> I have a list of users.
> User pressed "open in new tab" on John Smith -> persist key #43
> User pressed "open in new tab" on Jane Doe -> persist key #86 //
> doh!
> User now changes John Smith's data on the form and presses save.
>
> The currently persisted key for the edit form though is 86, not 43,
> so we end up overwriting Jane Doe's information instead of updating John
> Smith's information.
>
> I've resolved this problem by not using the Tapestry persistence
> layer and instead stuffing the key into a hidden field on the form, but it
> strikes me there has to be a way to make it work and still use the
> persistence layer.
>
> Can anyone offer some advice here? Is this just a case where I can't
> use Tapestry persistence?
>
> --- Pat
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multiple Instances of the Same Page and Persistence

Patrick Casey

        Yah, I'm on Firefox. I hadn't actually realized that IE's "Open in
New Window" spawned a new session, but if that's the case, that probably
explains why other folks haven't run into this before. With a new session in
every tab, the persistence problem I ran into wouldn't have hit.

        Firefox though lets you have multiple copies of the same page up,
all within the same session, and I'm starting to think that model is
incompatible with Tapestry 3.0's persistence strategy. It probably worked
fine when everyone was on IE, but maybe Firefox has broken it?

        One of the dev's will probably know for sure, but I'm leaning
towards that particular theory at the moment.

        For what it's worth a good workaround I found was to hide a hidden
key at the *top* of all my forms. Then when it gets set back during rewind
(it'll set first because it's on top), have *its* setter method bootstrap
the page back into the state you need it in for all the rest of the fields
to come back.

        Basically I now have my own static HashMap of page-persistent states
and send out a key with every form I generate. It's inelegant and not what
I'd recommend as a long term architecture, but it's working for now.

        --- Pat


> -----Original Message-----
> From: Bryan Lewis [mailto:[hidden email]]
> Sent: Saturday, May 07, 2005 1:37 PM
> To: Tapestry users
> Subject: Re: Multiple Instances of the Same Page and Persistence
>
> I don't have an answer for you, but I came across a similar problem a few
> days ago with Firefox.  I assume it's Firefox since you mentioned opening
> a
> new tab.
>
> When I access our site I get auto-logged-in with a cookie and get a new
> session as expected.  If I open a new tab and repeat the same URL, I get
> another view onto the *same* session.  No new login.  I can easily
> reproduce
> the nasty behavior you're seeing, without being as tricky as right-
> clicking
> a link to open it in a new tab.
>
> In fact if I start another instance of Firefox (a new browser window, not
> a
> tab) the same thing happens.  Doing this in IE starts a new session.  I've
> done a little googling and found another user complaining about this but
> no
> quick fixes.  Hoping someone else in this list has some expeirence with
> this.
>
>
<snip>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multiple Instances of the Same Page and Persistence

Patrick Casey
In reply to this post by Bryan Lewis
> -----Original Message-----
> From: Bryan Lewis [mailto:[hidden email]]
> Sent: Saturday, May 07, 2005 1:37 PM
> To: Tapestry users
> Subject: Re: Multiple Instances of the Same Page and Persistence
>
> I don't have an answer for you, but I came across a similar problem a few
> days ago with Firefox.  I assume it's Firefox since you mentioned opening
<snip>

        You know I'm actually not sure now that this is firefox related. I
fired up my copy of IE (6.0.29), logged into my app, then did:

        File->New Window ... Used Same Session as old window
        Right Click Link-> Open in new window ... Used same session as old
window

        So I'm a bit less confident this is firefox related now, except
maybe that nobody ever used to use "open in new window" with IE because it
clutters your desktop so badly. So maybe this has always been a risk and it
just only showed up in practice because only in Firefox are people actually
*using* the same form twice in one session?

        The plot thickens ...

        --- Pat




---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multiple Instances of the Same Page and Persistence

Johan Maasing
Patrick Casey wrote:

>>-----Original Message-----
>>From: Bryan Lewis [mailto:[hidden email]]
>>Sent: Saturday, May 07, 2005 1:37 PM
>>To: Tapestry users
>>Subject: Re: Multiple Instances of the Same Page and Persistence
>>
>>I don't have an answer for you, but I came across a similar problem a few
>>days ago with Firefox.  I assume it's Firefox since you mentioned opening
>
> <snip>
>
> You know I'm actually not sure now that this is firefox related. I
> fired up my copy of IE (6.0.29), logged into my app, then did:
>
> File->New Window ... Used Same Session as old window
> Right Click Link-> Open in new window ... Used same session as old
> window

This has always been the case, there is nothing preventing the browser
from opening several views to a server using the same session. Otherwise
how would for example pop-up windows work?
You have to take this into consideration no matter what web-framework
you use. If you think about it this is comes from the fact that HTTP is
a stateless protocol. Someone once described it as a fax-protocol. The
webserver sends a fax with the page - say an order form. The browser
faxes the users order (POST) to the server.
The server really has no clue which order-form the user looked at when
posting the data to the server. The page might not even have anything to
do with the page flow the programmer assumed, there is alweays the back
button, bookmarks, cached information, several windows and so on.
The best you can do is to try to detect that the information the browser
POSTs to the server is old and the user needs to see a fresh order form.
This is what Tapestry uses the rewind and stale link messages to tell
the user.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multiple Instances of the Same Page and Persistence

Patrick Casey
<snip>

        I don't think we're talking about the same thing here.

        I have two instances of the same page up.
        Neither is stale.
        Each is showing a different database object. One shows a Dog. The
other shows a Cat. The Dog was loaded first, then the Cat. If the user tries
to modify the Dog, its updates will get posted onto the Cat page because the
Cat is in persistent storage.
        Neither the dog, nor the cat, is stale. Both are still backed by
perfectly viable page objects. Both are still backed by a perfectly viable
session. Neither will throw the "stale page" flag if saved.
        The problem area lies in that Tapestry's persistence layer
overwrites the persistent properties of the "Dog" page with those of the
"Cat" page when it is loaded up within the same session.
        As I've mentioned before, I'm more than capable of working around
this behavior by the simple expedient of rolling my own persistence method.

        From where I'm sitting though the issue is this:

        The fact that I can't successfully persist two copies of the same
page within the same session basically makes the Tapestry Persistence layer
useless to me. I can't count on the users not doing "open in new window" or
"Open in new Tab".

        There's lots of doc out there though that references the tapestry
persistence layer and lots of people who sure seem to be using it. So my
question is:

        Is there a way to make the tapestry persistence layer work in the
situation I originally described? If not, why hasn't this been an issue for
other users? Is it a case that prior to firefox "open in new window" was
never used so this situation never cropped up? Or is there some sort of a
known workaround?

        --- Pat

>
> This has always been the case, there is nothing preventing the browser
> from opening several views to a server using the same session. Otherwise
> how would for example pop-up windows work?
> You have to take this into consideration no matter what web-framework
> you use. If you think about it this is comes from the fact that HTTP is
> a stateless protocol. Someone once described it as a fax-protocol. The
> webserver sends a fax with the page - say an order form. The browser
> faxes the users order (POST) to the server.
> The server really has no clue which order-form the user looked at when
> posting the data to the server. The page might not even have anything to
> do with the page flow the programmer assumed, there is alweays the back
> button, bookmarks, cached information, several windows and so on.
> The best you can do is to try to detect that the information the browser
> POSTs to the server is old and the user needs to see a fresh order form.
> This is what Tapestry uses the rewind and stale link messages to tell
> the user.




---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multiple Instances of the Same Page and Persistence

Bryan Lewis
In reply to this post by Johan Maasing
Johan Maasing wrote:


> This has always been the case, there is nothing preventing the browser
> from opening several views to a server using the same session. Otherwise
> how would for example pop-up windows work?

True.  Yet it seldom happens with IE (not that I'm a fan of IE) in the last
five years we've been running our app.  I guess most users don't use the
Ctrl-N new-window technique, instead preferring to start a new instance.
The concern we have with Firefox is that it's so easy to encounter the
problem; the safe old habit of starting a new browser is no longer safe.

The way we work around this is the Flow Synchronizer Token pattern that I
learned from this list some time ago.  Each form carries a simple ID as a
hidden field.  If the user submits a form that's not the one the server
thinks is the current one, a specific exception is thrown that we can catch
and show to the user as a reasonably friendly error page.  ("You've
submitted a form twice or a form other than the one expected...")  I don't
pretend that the users will totally grok this, but it's better than an
unexpected-error punt and the data doesn't get corrupted.




---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multiple Instances of the Same Page and Persistence

Patrick Casey
> The way we work around this is the Flow Synchronizer Token pattern that I
> learned from this list some time ago.  Each form carries a simple ID as a
> hidden field.  If the user submits a form that's not the one the server
> thinks is the current one, a specific exception is thrown that we can
> catch
> and show to the user as a reasonably friendly error page.  ("You've
> submitted a form twice or a form other than the one expected...")  I don't
> pretend that the users will totally grok this, but it's better than an
> unexpected-error punt and the data doesn't get corrupted.
>

        I ended up taking that approach a set further and rolling my own
persistence Manager. Now I stick a token in every form as you do, but
instead of throwing an error if it's out of synch, I go into my persistence
manager (the ubiquitous static hashmap) and yank out persistent properties
to fill up the page object, overwriting whatever Tapestry's persistence
manager put there.

        It's a decent amount of extra work on my end, but it seems to be
working and I'd recommend it as an approach if anyone else finds they need
to do the same thing.

        --- Pat



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multiple Instances of the Same Page and Persistence

Bryan Lewis
Good job.  Sounds like you're re-invented the old WebObjects backtracking
feature, a feature I didn't appreciate until I had to do without it.


----- Original Message -----
From: "Patrick Casey" <[hidden email]>
To: "'Tapestry users'" <[hidden email]>
Sent: Saturday, May 07, 2005 7:51 PM
Subject: RE: Multiple Instances of the Same Page and Persistence


> > The way we work around this is the Flow Synchronizer Token pattern that
I
> > learned from this list some time ago.  Each form carries a simple ID as
a
> > hidden field.  If the user submits a form that's not the one the server
> > thinks is the current one, a specific exception is thrown that we can
> > catch
> > and show to the user as a reasonably friendly error page.  ("You've
> > submitted a form twice or a form other than the one expected...")  I
don't
> > pretend that the users will totally grok this, but it's better than an
> > unexpected-error punt and the data doesn't get corrupted.
> >
>
> I ended up taking that approach a set further and rolling my own
> persistence Manager. Now I stick a token in every form as you do, but
> instead of throwing an error if it's out of synch, I go into my
persistence

> manager (the ubiquitous static hashmap) and yank out persistent properties
> to fill up the page object, overwriting whatever Tapestry's persistence
> manager put there.
>
> It's a decent amount of extra work on my end, but it seems to be
> working and I'd recommend it as an approach if anyone else finds they need
> to do the same thing.
>
> --- Pat
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multiple Instances of the Same Page and Persistence

Patrick Casey
Probably; I have a long and inglorious habit of reinventing the wheel only
to proudly display it and have somebody point out that the technique in
question has been in common use for at least two decades :).

Thing's I've (erroneously) thought I invented at one time or another:

Hash tables
Loop unrolling
Proxies

The hazards, I suppose, of not having a formal CS education :).

--- Pat

> -----Original Message-----
> From: Bryan Lewis [mailto:[hidden email]]
> Sent: Saturday, May 07, 2005 5:53 PM
> To: Tapestry users
> Subject: Re: Multiple Instances of the Same Page and Persistence
>
> Good job.  Sounds like you're re-invented the old WebObjects backtracking
> feature, a feature I didn't appreciate until I had to do without it.
>




---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Multiple Instances of the Same Page and Persistence

Todd O'Bryan
In reply to this post by Patrick Casey
On May 7, 2005, at 7:51 PM, Patrick Casey wrote:

>     I ended up taking that approach a set further and rolling my own
> persistence Manager. Now I stick a token in every form as you do, but
> instead of throwing an error if it's out of synch, I go into my  
> persistence
> manager (the ubiquitous static hashmap) and yank out persistent  
> properties
> to fill up the page object, overwriting whatever Tapestry's  
> persistence
> manager put there.
>

I don't pretend to understand the persistence layer or rewind (though  
I think I'm getting closer), but would this be solved by *not* having  
persistent properties and using hidden fields or some other page-
internal (and not session-persisted) device?

Todd


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Multiple Instances of the Same Page and Persistence

Patrick Casey

>
> I don't pretend to understand the persistence layer or rewind (though
> I think I'm getting closer), but would this be solved by *not* having
> persistent properties and using hidden fields or some other page-
> internal (and not session-persisted) device?
>
> Todd

<snip>

It would, and it's my traditional approach. I've found though that if you
have to persist a sizeable amount of data you end up with monsterous sets of
hidden fields on every form just to persist state. It gets pretty wasteful,
so it turns out to be more efficient to just pass around a key to the client
and then back again instead of having to serialize a whole mess of data and
then stream it back.

Ultimately though I'm more comfortable with the serialize it and stuff it in
a hidden field approach as your describe. Nonetheless for this particular
app I decided to go the other way (more or less to see how well it worked).

It actually seems to be working pretty well, so I'm losing a bit of my
prejudice against server-side state. So long as there's a context key on
every page I can use to get the *right* state out of the session I'm
reasonably comfortable with how it's working out. Without that context key
though, you're lost in a fever swamp of supposition as soon as the user
presses the back button.

        --- Pat



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]