Title: RE: [Wicket-develop] RequestCycle bug?

I believe that what you are seeing is correct. It cannot work any other way. The first request comes in and is processed and the temporary redirect is sent to the client (via a call to HttpServletResponse.sendRedirect(). This first request is then finished. Next, the redirect is received from the client as a NEW request and the page is rendered. In a clustered environment you may even get a situation where the first request arrives on one machine and the second request on a different one! It's nothing to do with Wicket, it the way redirects work in the Http protocol.

The problem is a pretty common one when using the 'redirect' pattern - you tend to end up doing lots of stuff twice (e.g. accessing hibernate sessions, loading business objects, security checks, audit and so on). First time you process request input and do updates of data, second time you read that data back in order to produce the output. It's a really nasty design pattern, especially when it's only purpose is to ensure that you get the correct browser URL in the address bar in order that a user doing a refresh gets the current page redrawn as opposed to resubmitting the previous data. In my opinion the HTTP protocol should have be fixed long ago so that responses can include a replacement URL for the browser bar so that a user can refresh a page without doing a repost of form data

As far as Wicket is concerned, Jon and I have been doing a fair bit of work to ensure this two-state-request mechanism works in a clustered environment (i.e. the first request should make changes to the session, while the request that handles the redirect should use the session as readonly). If you are not using detachable models then the handling of the redirect request is a pure render of inmemory data. If you are using detachable models then there is no alternative to getting a new hibernate session in order to reattach and reload the models again. This is the price you pay for keeping the session as small as possible and ensuring that you can scale and cluster.

There are some possible solutions:

- If session size and clustering is not an issue then you may be better to use non-detachable models for cases where data is very expensive to reload from the database. You could then manually detach it as some point when you know that rendering has completed if it was an issue.

- Perhaps we could come up with a 'partially detached model' that attaches when accessed but doesn't detach at the end of the first request (i.e. the model data stays in the session) if the request is going to send a redirect and does the detach at the end of the redirect request. Advantages are that you don't have to build the model data twice and that the model only lives attached in the session for the duration of the redirect. Disadvantage is that the model still lives in the session for a while.

- Don't use the redirect! This may be the best solution of them all. You can then use detachable models and all the features and know that they will only ever get used within a single request cycle. However, this makes much more work for you, the developer, as in every listener implementation you have to take control of deciding whether it was invoked because the user did actually submit something or because they did a refresh. I wonder if Wicket could do something to help with this? Unfortunatly adopting this approach doesn't stop the user getting the 'resubmit post form data' message when doing a page refresh. I suppose it's up to the app designer/customer as to whether this message is a problem or not!

Hope that clarifies how it all works?
Regards,
Chris


>
> Gentlemen,
>
> To my amazement, the request cycle doesn't work as expected: the
> processing of a request with a submit consists of the following
> RequestCycle calls:
>
> RequestCycle.onBeginRequest()
>     ... process page
>     ... form.onSubmit()
>     ... setResponsePage(...)
> RequestCycle.onEndRequest()
> redirect()!!!!!!!!!!!
> RequestCycle.onBeginRequest()
>     ... render page
> RequestCycle.onEndRequest()
>
> Where this goes wrong is when using the request cycle to
> store an open
> hibernate session, and supplying the response page /with/
> that session.
> After the redirect, /that/ session is closed (as should be done in
> onEndRequest()). When the response page is rendered, it uses a stale
> hibernate session.
>
> For the user this is strange: the redirect shouldn't split the
> requestcycle into two seperate cycles.
>
> Does anybody have a different view than I?
>
> Martijn
>
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from
> real users. Discover which products truly live up to the
> hype. Start reading now.
> http://ads.osdn.com/?ad_id=6595&alloc_id=14396> &op=click
>
> _______________________________________________
>
> Wicket-develop mailing list [email protected]
> https://lists.sourceforge.net/lists/listinfo/wicket-develop
>

Reply via email to