Re: T5: Persistence pains
Kalle Korhonen wrote: Hey Ivan, When you say we, who are you referring to? I mean my company. In my mind, this flow aka conversation support is absolutely the right solution for the problem. Are you planning to share the code or include it with some other project? Unfortunately, I can't. Various implementations of the conversation concept exists, but I'd gladly take a look at yours as I agree that embedding the flow key to the url is the best way to get support for multiple windows working correctly. It was modeled after the Spring Webflow. The same idea --- URL contains a key, which is used to get the data from the store. Every request generates new key. Kalle On Sat, May 3, 2008 at 11:03 PM, Ivan Dubrov [EMAIL PROTECTED] wrote: Right. Most annoying things for us about session and flash scopes was that they don't work in several tabs. And client can't hold too much data. That's why we have implemented a new persistence strategy named flow (inspired by the Spring WebFlow). The idea is that every URL has flow key stored in it, and the state is stored in the session under this key. The state is versioned (actually, the state is immutable, every change to the persistent fields introduces new state). We keep about 10 previous states, to keep the session from overburdening. There is still some issues with AJAX calls, though. The biggest argument to be made for request scope state that is automatically (or framework assisted developer code) persisted in the page vs. the flash technique of Tapestry is when considering multiple browsers opened by the user with the same session. Every app that I've developed, we've had to diligently ensure that nothing other than login credentials were stored in the session and everything was persisted within the request. For T3, our team developed an elaborate set of components that made this trivial (including our own annotations based support). The fact that Tap 5 gets in the way of trying to have a very light session is a little disconcerting. The other side-effect of flash would be thrashing in a clustered environment. - Original Message - From: Howard Lewis Ship [EMAIL PROTECTED] To: Tapestry users users@tapestry.apache.org Sent: Saturday, May 03, 2008 5:37 PM Subject: Re: T5: Persistence pains On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash
Re: T5: Persistence pains
The problem in client strategy that it used Serializable mechanism of jvm. Of cause it produce a lot of data (not getting in mind that most domain objects are not Serializable). I use own persistent strategy called 'parameter'. It is similar to client with follow exceptions. * It uses ValueEncoder to convert from Object to String and from String to Object. It save a lot of space, because for domain object only it id is persistent, which is rarely longer than 6 characters. * It persist each field in separate parameters (when client persist all data in parameter t:ac) . In this way it is similar to activation context's friendly url behavior. User see somethings like this http://somewhere.com/page?user=123order=12item=5 With help of this strategy I persist data between request to the same page. It solves both: problem with multiple browser tabs and problem with too many persistent fields in session. Ivan Dubrov wrote: Right. Most annoying things for us about “session” and “flash” scopes was that they don’t work in several tabs. And “client” can’t hold too much data. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: T5: Persistence pains
We use a serialization strategy that zips the serialized form and base64 encodes it. We're yet to see a performance issue with the solution. The issue with persisting each field in separate parameter is obviously that of the number of such fields you are able to persist. - Original Message - From: Dmitry Shyshkin [EMAIL PROTECTED] To: Tapestry users users@tapestry.apache.org Sent: Monday, May 05, 2008 4:48 AM Subject: Re: T5: Persistence pains The problem in client strategy that it used Serializable mechanism of jvm. Of cause it produce a lot of data (not getting in mind that most domain objects are not Serializable). I use own persistent strategy called 'parameter'. It is similar to client with follow exceptions. * It uses ValueEncoder to convert from Object to String and from String to Object. It save a lot of space, because for domain object only it id is persistent, which is rarely longer than 6 characters. * It persist each field in separate parameters (when client persist all data in parameter t:ac) . In this way it is similar to activation context's friendly url behavior. User see somethings like this http://somewhere.com/page?user=123order=12item=5 With help of this strategy I persist data between request to the same page. It solves both: problem with multiple browser tabs and problem with too many persistent fields in session. Ivan Dubrov wrote: Right. Most annoying things for us about “session” and “flash” scopes was that they don’t work in several tabs. And “client” can’t hold too much data. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: T5: Persistence pains
Howard, I totally get the two request pattern. A user shouldn't have to decide whether to re-submit their information. Great feature of the framework. So let's say that the request scope I'm referring to would be browser round-trip scope. As people on the forum have pointed out, combinations of the back button, refreshing, spawning new browser instances (which share session information) all can create chaos for any session-interacting web application. Just seems strange that seasoned web developers who use Tapestry are baking their own persistence mechanisms. Some are even making protocol-ish marker-based activation context constructs (/editdoohickeys/d1/keyval1/keyval2/d2/keyval1/keyval2). Sounds like what most of us are requesting is to at least permit the developer to not have to persist their components in the session (something like ServletRequest.setAttribute/getAttribute instead). Now that I've thoroughly beaten it, I'll just let the dead horse decompose for a while until it starts to smell (no Eight Belles reference intended). Joel -Original Message- From: Howard Lewis Ship [mailto:[EMAIL PROTECTED] Sent: Saturday, May 03, 2008 5:38 PM To: Tapestry users Subject: Re: T5: Persistence pains On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Storing these things in your component smells funny... but I don't know your app. If someone is coming to the page for the first time you want an empty object, if they are posting an update to the form then Tapestry is going to populate the values. If you are navigating within the page using pagelinks, but it's a form then I'd consider posting the form instead... Josh On Fri, May 2, 2008 at 2:39 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Sure Howard. Quite simply, the back button. When loading a page
Re: T5: Persistence pains
No, I get that there's an issue here ... I think conversational scope would be helpful. In addition, we need more smarts about what gets stored persistently, something like ValueEncoder but for persisted values; simple values (String, int, etc.) are find, but we need to recognize complex objects, such as Hibernate entities, and store just the entity id in the session, or as client-side data. On Mon, May 5, 2008 at 6:02 AM, Joel Wiegman [EMAIL PROTECTED] wrote: Howard, I totally get the two request pattern. A user shouldn't have to decide whether to re-submit their information. Great feature of the framework. So let's say that the request scope I'm referring to would be browser round-trip scope. As people on the forum have pointed out, combinations of the back button, refreshing, spawning new browser instances (which share session information) all can create chaos for any session-interacting web application. Just seems strange that seasoned web developers who use Tapestry are baking their own persistence mechanisms. Some are even making protocol-ish marker-based activation context constructs (/editdoohickeys/d1/keyval1/keyval2/d2/keyval1/keyval2). Sounds like what most of us are requesting is to at least permit the developer to not have to persist their components in the session (something like ServletRequest.setAttribute/getAttribute instead). Now that I've thoroughly beaten it, I'll just let the dead horse decompose for a while until it starts to smell (no Eight Belles reference intended). Joel -Original Message- From: Howard Lewis Ship [mailto:[EMAIL PROTECTED] Sent: Saturday, May 03, 2008 5:38 PM To: Tapestry users Subject: Re: T5: Persistence pains On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize
Re: T5: Persistence pains
Hey Ivan, When you say we, who are you referring to? In my mind, this flow aka conversation support is absolutely the right solution for the problem. Are you planning to share the code or include it with some other project? Various implementations of the conversation concept exists, but I'd gladly take a look at yours as I agree that embedding the flow key to the url is the best way to get support for multiple windows working correctly. Kalle On Sat, May 3, 2008 at 11:03 PM, Ivan Dubrov [EMAIL PROTECTED] wrote: Right. Most annoying things for us about session and flash scopes was that they don't work in several tabs. And client can't hold too much data. That's why we have implemented a new persistence strategy named flow (inspired by the Spring WebFlow). The idea is that every URL has flow key stored in it, and the state is stored in the session under this key. The state is versioned (actually, the state is immutable, every change to the persistent fields introduces new state). We keep about 10 previous states, to keep the session from overburdening. There is still some issues with AJAX calls, though. The biggest argument to be made for request scope state that is automatically (or framework assisted developer code) persisted in the page vs. the flash technique of Tapestry is when considering multiple browsers opened by the user with the same session. Every app that I've developed, we've had to diligently ensure that nothing other than login credentials were stored in the session and everything was persisted within the request. For T3, our team developed an elaborate set of components that made this trivial (including our own annotations based support). The fact that Tap 5 gets in the way of trying to have a very light session is a little disconcerting. The other side-effect of flash would be thrashing in a clustered environment. - Original Message - From: Howard Lewis Ship [EMAIL PROTECTED] To: Tapestry users users@tapestry.apache.org Sent: Saturday, May 03, 2008 5:37 PM Subject: Re: T5: Persistence pains On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way
Re: T5: Persistence pains
Right. Most annoying things for us about “session” and “flash” scopes was that they don’t work in several tabs. And “client” can’t hold too much data. That’s why we have implemented a new persistence strategy named “flow” (inspired by the Spring WebFlow). The idea is that every URL has flow key stored in it, and the state is stored in the session under this key. The state is versioned (actually, the state is immutable, every change to the persistent fields introduces new state). We keep about 10 previous states, to keep the session from overburdening. There is still some issues with AJAX calls, though. The biggest argument to be made for request scope state that is automatically (or framework assisted developer code) persisted in the page vs. the flash technique of Tapestry is when considering multiple browsers opened by the user with the same session. Every app that I've developed, we've had to diligently ensure that nothing other than login credentials were stored in the session and everything was persisted within the request. For T3, our team developed an elaborate set of components that made this trivial (including our own annotations based support). The fact that Tap 5 gets in the way of trying to have a very light session is a little disconcerting. The other side-effect of flash would be thrashing in a clustered environment. - Original Message - From: Howard Lewis Ship [EMAIL PROTECTED] To: Tapestry users users@tapestry.apache.org Sent: Saturday, May 03, 2008 5:37 PM Subject: Re: T5: Persistence pains On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Storing these things in your component smells funny... but I don't know your app. If someone is coming to the page for the first time you want an empty object, if they are posting an update to the form then Tapestry is going to populate
Re: T5: Persistence pains
On Sun, May 4, 2008 at 3:03 AM, Ivan Dubrov [EMAIL PROTECTED] wrote: Right. Most annoying things for us about session and flash scopes was that they don't work in several tabs. And client can't hold too much data. Maybe you're having an issue with the statelessness of HTTP, not with Tapestry itself. -- Thiago - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: T5: Persistence pains
I am not sure if this is what you need, but I had problem similar to yours and solved it this way: You wrote: 1) @Persist(session) - Obviously doesn't work well for just persisting values between requests, unless someone has come up with a reliable construct for nulling out these values whenever someone leaves the page? I have page registerUser, where I want user to have clear fields every time he enters the page. All fields are market @Persist @Persist private String name; @Persist private String surname; // etc... To solve clearing both fields values and error messages on each page exit I use method cleanupRender() where I put clearErrors() and discardPersistentFieldChanges(). @Inject private ComponentResources componentResources; void cleanupRender() { componentResources.discardPersistentFieldChanges(); registerForm.clearErrors(); } // discardPersistentFieldChanges() from T5 api: Discards all persistent field changes for the page containing the component. Changes are eliminated from persistent storage (such as the Session) which will take effect in the next request (the attached page instance is not affected). Regards -- Tomasz Dziurko - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: T5: Persistence pains
On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Storing these things in your component smells funny... but I don't know your app. If someone is coming to the page for the first time you want an empty object, if they are posting an update to the form then Tapestry is going to populate the values. If you are navigating within the page using pagelinks, but it's a form then I'd consider posting the form instead... Josh On Fri, May 2, 2008 at 2:39 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Sure Howard. Quite simply, the back button. When loading a page with an activation context, say: http://myapp.com/editproduct/20 (where 20 is a product ID) I'll initialize some flash-persistable values on the page from the Product whose ID is 20. Now if the user clicks on the Back button and goes to a link that reuses the same screen but without a context, say: http://myapp.com/editproduct/ (let's say this page should blank out the screen so the user can enter a new product) Most of my flash-persistable values (from Product 20) will still be on the screen. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Are these scenarios valid? -Original Message- From: Howard Lewis Ship [mailto:[EMAIL PROTECTED] Sent: Friday, May 02, 2008 5:17 PM To: Tapestry users Subject: Re: T5: Persistence pains Could you elaborate on why the flash persistence strategy is insufficient for your needs? On Fri, May 2, 2008 at 2:00 PM, Joel Wiegman [EMAIL PROTECTED] wrote: All, Maybe I'm missing something here, maybe I'm
Re: T5: Persistence pains
The biggest argument to be made for request scope state that is automatically (or framework assisted developer code) persisted in the page vs. the flash technique of Tapestry is when considering multiple browsers opened by the user with the same session. Every app that I've developed, we've had to diligently ensure that nothing other than login credentials were stored in the session and everything was persisted within the request. For T3, our team developed an elaborate set of components that made this trivial (including our own annotations based support). The fact that Tap 5 gets in the way of trying to have a very light session is a little disconcerting. The other side-effect of flash would be thrashing in a clustered environment. - Original Message - From: Howard Lewis Ship [EMAIL PROTECTED] To: Tapestry users users@tapestry.apache.org Sent: Saturday, May 03, 2008 5:37 PM Subject: Re: T5: Persistence pains On Fri, May 2, 2008 at 6:36 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. It's not resistance, it's a different mindset, one that states that URLs should stand on their own in the browser and represent data to be presented to the user (i.e., render page requests) rather than behaviors to execute (the action requests). From what you describe, your activate event handler method should be able to load whatever additional data is needed and store it in simple component fields: that's your request scope. The fact that Tapestry links action requests to page requests is a separate issue. The goal is that if the user clicks the refresh button (the other annoying thing users do, besides hit the browser back button) that there won't be unexpected side-effects (such as, for instance, re-submitting an order, re-sending an email, etc., etc.). The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? Because we can store it inside ordinary fields instead? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! It would be interesting to see what some of these values are that can only be set inside an action request but must then span into a render request. Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Storing these things in your component smells funny... but I don't know your app. If someone is coming to the page for the first time you want an empty object, if they are posting an update to the form then Tapestry is going to populate the values. If you are navigating within the page using pagelinks, but it's a form then I'd consider posting the form instead... Josh On Fri, May 2, 2008 at 2:39 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Sure Howard. Quite simply, the back button. When loading a page with an activation context, say: http://myapp.com/editproduct/20 (where 20 is a product ID) I'll initialize some flash-persistable values on the page from the Product whose ID is 20. Now if the user clicks on the Back button and goes to a link that reuses the same screen but without
Re: T5: Persistence pains
Could you elaborate on why the flash persistence strategy is insufficient for your needs? On Fri, May 2, 2008 at 2:00 PM, Joel Wiegman [EMAIL PROTECTED] wrote: All, Maybe I'm missing something here, maybe I'm not, but I'm attempting to preserve state JUST BETWEEN REQUESTS and I'm really struggling (I know in T5 there's really two requests, but for simplicity's sake let's just call the round trip from the browser a request). My options are: 1) @Persist(session) - Obviously doesn't work well for just persisting values between requests, unless someone has come up with a reliable construct for nulling out these values whenever someone leaves the page? 2) @Persist(flash) - This is really only useful for messages and other objects that are reliably referenced once. This is NOT request-scoped persistence. 3) @Persist(client) - While I thought initially thought that this would solve all my woes, instead every link in my application now carries around an huge encoded state variable in the URL. I'm completely missing the benefit of this versus just using session persistence (enlightenment appreciated). 4) Activation context magic - While this does make for clean and nifty URLs, the hassle of constructing the identifiers for complex objects and creating the contexts for them has not proven worth it to me (hint: composite primary keys are almost unusable). Also, if your page uses more than one dynamically-sized collection of objects, then you're out of luck. PLEASE PLEASE don't interpret this as Tapestry-bashing. Tapestry has been a delight to work with compared to previous frameworks I've used. I'm just really struggling with how to do something that, IMHO, a web framework should make very simple (request-scoped persistence). Anyone solve this riddle yet? Joel - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: T5: Persistence pains
Sure Howard. Quite simply, the back button. When loading a page with an activation context, say: http://myapp.com/editproduct/20 (where 20 is a product ID) I'll initialize some flash-persistable values on the page from the Product whose ID is 20. Now if the user clicks on the Back button and goes to a link that reuses the same screen but without a context, say: http://myapp.com/editproduct/ (let's say this page should blank out the screen so the user can enter a new product) Most of my flash-persistable values (from Product 20) will still be on the screen. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Are these scenarios valid? -Original Message- From: Howard Lewis Ship [mailto:[EMAIL PROTECTED] Sent: Friday, May 02, 2008 5:17 PM To: Tapestry users Subject: Re: T5: Persistence pains Could you elaborate on why the flash persistence strategy is insufficient for your needs? On Fri, May 2, 2008 at 2:00 PM, Joel Wiegman [EMAIL PROTECTED] wrote: All, Maybe I'm missing something here, maybe I'm not, but I'm attempting to preserve state JUST BETWEEN REQUESTS and I'm really struggling (I know in T5 there's really two requests, but for simplicity's sake let's just call the round trip from the browser a request). My options are: 1) @Persist(session) - Obviously doesn't work well for just persisting values between requests, unless someone has come up with a reliable construct for nulling out these values whenever someone leaves the page? 2) @Persist(flash) - This is really only useful for messages and other objects that are reliably referenced once. This is NOT request-scoped persistence. 3) @Persist(client) - While I thought initially thought that this would solve all my woes, instead every link in my application now carries around an huge encoded state variable in the URL. I'm completely missing the benefit of this versus just using session persistence (enlightenment appreciated). 4) Activation context magic - While this does make for clean and nifty URLs, the hassle of constructing the identifiers for complex objects and creating the contexts for them has not proven worth it to me (hint: composite primary keys are almost unusable). Also, if your page uses more than one dynamically-sized collection of objects, then you're out of luck. PLEASE PLEASE don't interpret this as Tapestry-bashing. Tapestry has been a delight to work with compared to previous frameworks I've used. I'm just really struggling with how to do something that, IMHO, a web framework should make very simple (request-scoped persistence). Anyone solve this riddle yet? Joel - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: T5: Persistence pains
Hi Joel, First, PLEASE PLEASE don't interpret this as Tapestry-bashing. Yikes, hopefully the troll-bashing hasn't made people afraid to ask tough questions for fear of being labeled troll. Anyway, back you your question. So, when you render a page you want some state that was used to render that page to be available the next time you render the page. You don't want that state hanging around in the session if the user leaves that page? 3) @Persist(client) - While I thought initially thought that this would solve all my woes, instead every link in my application now carries around an huge encoded state variable in the URL. I'm completely missing the benefit of this versus just using session persistence (enlightenment appreciated). @Persist(client) is better than @Persist(session) when you're either unable or choosing to not use sessions. It also prevents you from having to deal with expired sessions. If the user goes away and comes back an hour later, the page should still work. 4) Activation context magic ... (hint: composite primary keys are almost unusable). Can you be more specific about your trouble with composite keys? Also, if your page uses more than one dynamically-sized collection of objects, then you're out of luck. I've used markers for cases where I was stowing different types of context in the url. http://localhost/m1/one/two/m2/hello/world Somewhere there is code floating around for cookie based persistence. That gets it onto the client without putting it in the url. If you're concerned about the same session being opened in two browsers, there is also an implementation of conversation in the latest jumpstart that you could take a look at... Of course, these are tied to page and component. If you want a cookie based Application State Object that you can pass between pages, I think you'll have to write that one up. If you really want to make sure that you aren't using data intended for a different instance of the page, you could tie the object in the cookie to an activation context value. If they don't match assume that you're in a wonky state and clear it out. Josh On Fri, May 2, 2008 at 2:00 PM, Joel Wiegman [EMAIL PROTECTED] wrote: All, Maybe I'm missing something here, maybe I'm not, but I'm attempting to preserve state JUST BETWEEN REQUESTS and I'm really struggling (I know in T5 there's really two requests, but for simplicity's sake let's just call the round trip from the browser a request). My options are: 1) @Persist(session) - Obviously doesn't work well for just persisting values between requests, unless someone has come up with a reliable construct for nulling out these values whenever someone leaves the page? 2) @Persist(flash) - This is really only useful for messages and other objects that are reliably referenced once. This is NOT request-scoped persistence. 3) @Persist(client) - While I thought initially thought that this would solve all my woes, instead every link in my application now carries around an huge encoded state variable in the URL. I'm completely missing the benefit of this versus just using session persistence (enlightenment appreciated). 4) Activation context magic - While this does make for clean and nifty URLs, the hassle of constructing the identifiers for complex objects and creating the contexts for them has not proven worth it to me (hint: composite primary keys are almost unusable). Also, if your page uses more than one dynamically-sized collection of objects, then you're out of luck. PLEASE PLEASE don't interpret this as Tapestry-bashing. Tapestry has been a delight to work with compared to previous frameworks I've used. I'm just really struggling with how to do something that, IMHO, a web framework should make very simple (request-scoped persistence). Anyone solve this riddle yet? Joel - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- -- TheDailyTube.com. Sign up and get the best new videos on the internet delivered fresh to your inbox. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: T5: Persistence pains
On 5/2/08, Joel Wiegman [EMAIL PROTECTED] wrote: Quite simply, the back button. When loading a page with an activation context, say: I noticed what you described in it is not a problem with Tapestry (at least most of the time), it's a browser cache or browser prefilling forms issue. Take a look at that, looking at the generated HTML after you hit the back button. It can be the case. -- Thiago - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: T5: Persistence pains
I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Storing these things in your component smells funny... but I don't know your app. If someone is coming to the page for the first time you want an empty object, if they are posting an update to the form then Tapestry is going to populate the values. If you are navigating within the page using pagelinks, but it's a form then I'd consider posting the form instead... Josh On Fri, May 2, 2008 at 2:39 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Sure Howard. Quite simply, the back button. When loading a page with an activation context, say: http://myapp.com/editproduct/20 (where 20 is a product ID) I'll initialize some flash-persistable values on the page from the Product whose ID is 20. Now if the user clicks on the Back button and goes to a link that reuses the same screen but without a context, say: http://myapp.com/editproduct/ (let's say this page should blank out the screen so the user can enter a new product) Most of my flash-persistable values (from Product 20) will still be on the screen. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Are these scenarios valid? -Original Message- From: Howard Lewis Ship [mailto:[EMAIL PROTECTED] Sent: Friday, May 02, 2008 5:17 PM To: Tapestry users Subject: Re: T5: Persistence pains Could you elaborate on why the flash persistence strategy is insufficient for your needs? On Fri, May 2, 2008 at 2:00 PM, Joel Wiegman [EMAIL PROTECTED] wrote: All, Maybe I'm missing something here, maybe I'm not, but I'm attempting to preserve state JUST BETWEEN REQUESTS and I'm really struggling (I know in T5 there's really two requests, but for simplicity's sake let's just call the round trip from the browser a request). My options are: 1) @Persist(session) - Obviously doesn't work well for just persisting values between requests, unless someone has come up with a reliable construct for nulling out these values whenever someone leaves the page? 2) @Persist(flash) - This is really only useful for messages and other objects that are reliably referenced once. This is NOT request-scoped persistence. 3) @Persist(client) - While I thought initially thought that this would solve all my woes, instead every link in my application now carries around an huge encoded state variable in the URL. I'm completely missing the benefit of this versus just using session persistence (enlightenment appreciated). 4) Activation context magic - While this does make for clean and nifty URLs, the hassle of constructing the identifiers for complex objects and creating the contexts for them has not proven worth it to me (hint: composite primary keys are almost unusable). Also, if your page uses more than one dynamically-sized collection of objects, then you're out of luck. PLEASE PLEASE don't interpret this as Tapestry-bashing. Tapestry has been a delight to work with compared to previous frameworks I've used. I'm just really struggling with how to do something that, IMHO, a web framework should make very simple (request-scoped persistence). Anyone solve this riddle yet? Joel - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- -- TheDailyTube.com. Sign up and get the best new videos on the internet delivered fresh to your inbox. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: T5: Persistence pains
Josh, Thanks for the great suggestions. I guess I'm still befuddled as to why a web framework would resist having a request scope so dilligently. The flash scope appears to makes some intelligent guesses as to when you want your objects removed from the session, but the back-button-example I listed is one of quite a few reasons why making such guesses is a fools game. As we all know, HTTP is a request-response, stateless protocol, but Tapestry appears to be resisting storing state in one of the most basic constructs available in HTTP... the request. Anyone know why this is? As you illustrated, I'm sure there are quite a few elaborate ways of dancing around the issue in any application (redundant checking, re-verification, passing clearThisValue flags around, etc.). None seem very elegant though (and would probably be associated with this is why I'm doing this comments). As for your activation context suggestions, those are some neat ideas. I hadn't considered your marking suggestion. I'm a little afraid to use it though. I can see a Tapestry pattern evolving from that that yields (String... stuff) as your parameter to your onActivate with a boatload of extravagant logic. Anyway, still haven't heard a useful suggestion to get objects into a request only scope. If anyone can think of something please post! Thanks, Joel -Original Message- From: [EMAIL PROTECTED] on behalf of Josh Canfield Sent: Fri 5/2/2008 6:31 PM To: Tapestry users Subject: Re: T5: Persistence pains I generally consider flash persistence as a way to get an object from the action request to the render request... If you're going to set it in the render request you should consider adding code that validates that your data and context match up. You could, for instance, also flash persist your id and check it against the id from the context. If they don't match then null your other properties. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Storing these things in your component smells funny... but I don't know your app. If someone is coming to the page for the first time you want an empty object, if they are posting an update to the form then Tapestry is going to populate the values. If you are navigating within the page using pagelinks, but it's a form then I'd consider posting the form instead... Josh On Fri, May 2, 2008 at 2:39 PM, Joel Wiegman [EMAIL PROTECTED] wrote: Sure Howard. Quite simply, the back button. When loading a page with an activation context, say: http://myapp.com/editproduct/20 (where 20 is a product ID) I'll initialize some flash-persistable values on the page from the Product whose ID is 20. Now if the user clicks on the Back button and goes to a link that reuses the same screen but without a context, say: http://myapp.com/editproduct/ (let's say this page should blank out the screen so the user can enter a new product) Most of my flash-persistable values (from Product 20) will still be on the screen. While some may argue that this is just poor design, what if the fields I initialize varies by product? I'd get a merging of the two products on the screen depending on what was persisted first. Are these scenarios valid? -Original Message- From: Howard Lewis Ship [mailto:[EMAIL PROTECTED] Sent: Friday, May 02, 2008 5:17 PM To: Tapestry users Subject: Re: T5: Persistence pains Could you elaborate on why the flash persistence strategy is insufficient for your needs? On Fri, May 2, 2008 at 2:00 PM, Joel Wiegman [EMAIL PROTECTED] wrote: All, Maybe I'm missing something here, maybe I'm not, but I'm attempting to preserve state JUST BETWEEN REQUESTS and I'm really struggling (I know in T5 there's really two requests, but for simplicity's sake let's just call the round trip from the browser a request). My options are: 1) @Persist(session) - Obviously doesn't work well for just persisting values between requests, unless someone has come up with a reliable construct for nulling out these values whenever someone leaves the page? 2) @Persist(flash) - This is really only useful for messages and other objects that are reliably referenced once. This is NOT request-scoped persistence. 3) @Persist(client) - While I thought initially thought that this would solve all my woes, instead every link in my application now carries around an huge encoded state variable in the URL. I'm completely missing the benefit of this versus just using session persistence (enlightenment appreciated). 4) Activation context magic - While this does make for clean and nifty URLs, the hassle of constructing the identifiers for complex objects and creating the contexts for them has not proven worth it to me (hint: composite primary keys