Wicket
  1. Wicket
  2. WICKET-1471

FeedbackPanel does not work properly in clustered environment

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.3.2
    • Fix Version/s: 1.3.5
    • Component/s: None
    • Labels:
      None

      Description

      Environment: Tomcat 5.5.25, Java 6, non-sticky session clustering, redirect to render strategy.

      Consider the following scenario:

      • Two tomcat instances running a Wicket application in clustered mode
      • Application contains a page that has a form and a feedback panel
      • Web browser posts the form. The post is processed in cluster node A
      • Application in cluster node A validates the form and produces some feedback messages
      • Request ends, Wicket ->clears all component feedback messages from the session<- , replicates the session, and issues a redirect to render the page
      • Browser follows the redirect and hits the application in node B
      • Application in node B renders the page but, because there are no feedback messages on the session , the feedback panel is not made visible

      The solution I found (don't know if its the best one) is to change WebSession.java to clear component feedback messages only if the current request is not a redirect.
      This solution breaks one test case (WicketTesterTest) because it takes the broken behavior for granted.

      I will attach a patch to WebSession and to WicketTesterTest.

      1. WebSession.patch
        0.8 kB
        Juliano Viana
      2. WicketTesterTest.patch
        3 kB
        Juliano Viana

        Activity

        Hide
        Johan Compagner added a comment -

        hmm is the big if there:

        if (Application.get().getRequestCycleSettings().getRenderStrategy() != IRequestCycleSettings.REDIRECT_TO_RENDER ||
        ((WebRequest)RequestCycle.get().getRequest()).isAjax() ||
        (!RequestCycle.get().isRedirect()))

        not trying to do what you are fixing?

        I think we mean && instead of || somehow there.

        Show
        Johan Compagner added a comment - hmm is the big if there: if (Application.get().getRequestCycleSettings().getRenderStrategy() != IRequestCycleSettings.REDIRECT_TO_RENDER || ((WebRequest)RequestCycle.get().getRequest()).isAjax() || (!RequestCycle.get().isRedirect())) not trying to do what you are fixing? I think we mean && instead of || somehow there.
        Hide
        Johan Compagner added a comment -

        shouldnt the if be just this:

        if (!(Application.get().getRequestCycleSettings().getRenderStrategy() == IRequestCycleSettings.REDIRECT_TO_RENDER && RequestCycle.get()
        .isRedirect()) ||
        ((WebRequest)RequestCycle.get().getRequest()).isAjax())

        the messages should be cleared when it is an ajax request (always)
        and when it is not a redirect in a redirect_to_render strategy.

        Show
        Johan Compagner added a comment - shouldnt the if be just this: if (!(Application.get().getRequestCycleSettings().getRenderStrategy() == IRequestCycleSettings.REDIRECT_TO_RENDER && RequestCycle.get() .isRedirect()) || ((WebRequest)RequestCycle.get().getRequest()).isAjax()) the messages should be cleared when it is an ajax request (always) and when it is not a redirect in a redirect_to_render strategy.
        Hide
        Juliano Viana added a comment -

        Hi,

        The problem as I see it is with the line:
        getFeedbackMessages().clear(WebSession.MESSAGES_FOR_COMPONENTS);

        This line does not depend upon the above if statement- maybe it should be included on it ? I don't know what is the precise difference between session scoped messages and component messages, but clearing component messages on a redirect request is the cause of the problem.

        Show
        Juliano Viana added a comment - Hi, The problem as I see it is with the line: getFeedbackMessages().clear(WebSession.MESSAGES_FOR_COMPONENTS); This line does not depend upon the above if statement- maybe it should be included on it ? I don't know what is the precise difference between session scoped messages and component messages, but clearing component messages on a redirect request is the cause of the problem.
        Hide
        Johan Compagner added a comment -

        it is exactly that line.
        the patch you do is exactly that.
        And it think the if above it is just that. It should only clear when a rendering did happens onces for those components.

        And i guess that is when it is an ajax request or if it Not redirect to render with a redirect (so it is a one pass render or render to buffer)

        Show
        Johan Compagner added a comment - it is exactly that line. the patch you do is exactly that. And it think the if above it is just that. It should only clear when a rendering did happens onces for those components. And i guess that is when it is an ajax request or if it Not redirect to render with a redirect (so it is a one pass render or render to buffer)
        Hide
        Juliano Viana added a comment -

        Hi,

        I'm beginning to realize that my original interpretation of the bug is wrong.
        First of all the app is not using redirect to render strategy, its using redirect to buffer strategy.
        So the original problem should not have happened in the first place.
        The reason why it did happen is completely different than I thought: in redirect to buffer, the buffered response is kept in a HashMap in the WebApplication class (bufferedResponses), and this is not clustered at all.
        So when the second request hits the other cluster server, the other server has no choice but to re-render the page again. And that means the application is behaving as a REDIRECT_TO_RENDER application but with REDIRECT_TO_BUFFER settings. This in turn causes the feedback messages to be cleared too soon.
        So my patch is just a workaround (and it introduces some subtle bugs). I suggest this issue be closed and replaced with an issue to fix the redirect to buffer strategy in a clustered environment.

        • Juliano
        Show
        Juliano Viana added a comment - Hi, I'm beginning to realize that my original interpretation of the bug is wrong. First of all the app is not using redirect to render strategy, its using redirect to buffer strategy. So the original problem should not have happened in the first place. The reason why it did happen is completely different than I thought: in redirect to buffer, the buffered response is kept in a HashMap in the WebApplication class (bufferedResponses), and this is not clustered at all. So when the second request hits the other cluster server, the other server has no choice but to re-render the page again. And that means the application is behaving as a REDIRECT_TO_RENDER application but with REDIRECT_TO_BUFFER settings. This in turn causes the feedback messages to be cleared too soon. So my patch is just a workaround (and it introduces some subtle bugs). I suggest this issue be closed and replaced with an issue to fix the redirect to buffer strategy in a clustered environment. Juliano
        Hide
        Matej Knopp added a comment -

        If you use Wicket on cluster with REDIRECT_TO_BUFFER you should always be using sticky sessions.

        Show
        Matej Knopp added a comment - If you use Wicket on cluster with REDIRECT_TO_BUFFER you should always be using sticky sessions.

          People

          • Assignee:
            Unassigned
            Reporter:
            Juliano Viana
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development