1 2 Previous Next 28 Replies Latest reply on Sep 7, 2007 8:19 AM by vincent.latombe Go to original post
      • 15. Re: Problems using ajax validation in seam-gen
        pmuir

        Damien: yes, I can reproduce.

        I don't think Vincent's patch will make it into Seam. Currently Seam serializes concurrent requests to Conversational scoped beans (failing if it has to wait longer that the concurrent-request-timeout).

        Vincent's patch (afaics) alters this to allow concurrent access to conversational scoped beans (which IIRC will fail when accessing SFSBs) - though I'm not sure of Vincent's exact intention as he says he is serializing calls to getTotal - but I think he is actually parallelizing calls.

        I need to spend some time looking at this part of Seam (I'm not overly familiar with it) and talk to Seam/Richfaces dev on this.

        • 16. Re: Problems using ajax validation in seam-gen
          damianharvey

          Thanks Pete. Nice to know that it's on the radar and even nicer to have this finally pinned down to a reproducible bug.

          Cheers,

          Damian.

          • 17. Re: Problems using ajax validation in seam-gen

            Pete : I think you misread my patch. Concurrent calls don't get parallelized. I didn't really understand what this concurrent request timeout really represents, but it seems awkward to me that a request has to fail because an existing request is already being processed. I changed the behaviour from "wait for the timeout" to "wait for the current action to finish".

            You could still say : "ok let's increase the request timeout".... but you're just postponing the problem because if you take a stack of conversation events to be processed, for them to be processed correctly they need to be all executed within a shorter time than the timeout.

            • 18. Re: Problems using ajax validation in seam-gen
              damianharvey

              Maybe it needs a similar mechanism to the eventsQueue used by ajax4jsf (ironically).

              • 19. Re: Problems using ajax validation in seam-gen
                pmuir

                Vincent, yes, I understand your patch better now :) So, I want to understand better what you guys *want* the behaviour to be.

                I've attempted to summarise the current behaviour:

                Each received ajax request is processed by Seam in serial. If concurrent calls occur, Seam queues the action event for a period of time (the concurrent request timeout), if it can't process the event within that period it aborts the call and prints out a FacesMessage telling us this. You can adjust the concurrent request timeout globally (through components.xml) or on a request by request basis (through Manager.instance().setConcurrentRequestTimeout();) - and obviously you can queue etc. events on the client side through a4j.

                So, Seam has the equivalent of both eventsQueue (always on) and requestDelay (perhaps hard to set on a request by request basis), it doesn't have an equivalent of ignoreDupRequests.

                Now, my parallel processing stuff is a bit rusty, but looking at ReentrantLock, and at Vincent's patch, I think it, is the equivalent of setting an infinitely long concurrentRequestTimeout - so that requests are delayed indefinitely until they can be scheduled.

                So - what can we do to make this better?

                1) Document this (much) better based on discussions in this thread

                2) Make it easier to set the concurrentRequestTimeout on an action by action basis e.g.

                @ConcurentRequestTime(5000)
                public void doSomething() {}


                3) Provide something equivalent to ignoreDupRequests (so that multiple concurrent calls to the same method can be discarded).

                4) Make it easier to disable the warning message on a per request basis - it really means one thing if your conversation times out as you were idle (in this case you want something like "Sorry, you were idle too long and your workspace has been lost") and something completely different if you have a concurrent request timeout ("Sorry, you are swamping the server, please slow down!")

                Comments welcome :)

                • 20. Re: Problems using ajax validation in seam-gen
                  atao

                  Vincent said.


                  The issue comes from the fact that when I hit the Save button, the onblur event from a:support fires at the same time and it breaks the save process. If I click outside the edited field, and then click the save button it works.


                  so I tried this workaround:
                  <a:support event="onblur" reRender="cityNameDecoration" bypassUpdates="true" onsubmit="this.getElement('0').focus();"/>
                  

                  in the edit pages generated by: it works fine in this case!


                  • 21. Re: Problems using ajax validation in seam-gen

                    Pete: thanks for your explanations, I think I have a clear and complete understanding of the situation now. See my comments inline.

                    Now, my parallel processing stuff is a bit rusty, but looking at ReentrantLock, and at Vincent's patch, I think it, is the equivalent of setting an infinitely long concurrentRequestTimeout - so that requests are delayed indefinitely until they can be scheduled.

                    It is exactly what I intended to do.

                    "pete.muir@jboss.org" wrote:

                    So - what can we do to make this better?

                    1) Document this (much) better based on discussions in this thread

                    That would be a good stard. But even with better documentation, there is a need for a better control of these timeout problems.

                    "pete.muir@jboss.org" wrote:

                    2) Make it easier to set the concurrentRequestTimeout on an action by action basis e.g.

                    @ConcurentRequestTime(5000)
                    public void doSomething() {}



                    It's interesting, but won't really solve the flooding problem. As far as I understood the code, the timeout is constant, not depending on the number of calls waiting for conversation lock. And does this timeout represents the amount of time the call must wait before failing, or is it the amount of time we estimate this call should take?

                    I think the second option is better. A method should declare how much time it typically takes to execute, so that if a new call occurs, it can wait for this time. By extension, if we have n calls waiting and we've got a n+1-th call coming, this new call must take into consideration all timeouts defined by previous calls and sum them up, to determine the amount of time it should wait.

                    "pete.muir@jboss.org" wrote:

                    3) Provide something equivalent to ignoreDupRequests (so that multiple concurrent calls to the same method can be discarded).

                    That would be great too to prevent flooding cases more easily
                    "pete.muir@jboss.org" wrote:


                    4) Make it easier to disable the warning message on a per request basis - it really means one thing if your conversation times out as you were idle (in this case you want something like "Sorry, you were idle too long and your workspace has been lost") and something completely different if you have a concurrent request timeout ("Sorry, you are swamping the server, please slow down!")


                    • 22. Re: Problems using ajax validation in seam-gen
                      damianharvey

                      Pete said:

                      If concurrent calls occur, Seam queues the action event for a period of time (the concurrent request timeout), if it can't process the event within that period it aborts the call and prints out a FacesMessage telling us this.


                      Pete, if I understand you correctly, then I don't think that this is what is happening. When the period times out it doesn't just abort the call, it ends the conversation. If you compare a Conversation to a Session, you wouldn't expect a Session to expire just because a page couldn't load.

                      As you say in option 3, something like ignoreDupRequests would be handy, but sometimes you may well want the behaviour that Vincent has coded - ie. I want all of my requests to be processed eventually (within reason). Mind you I suppose that could be accomplished with a very long timeout...

                      I've tried increasing the concurrent-request-timeout to 10 seconds and the test page from the previous posts works fine. The calls all get queued and everything is cool and I'm a happy bunny.

                      What are the downsides of increasing this timeout? For instance what is the danger in setting it to a stupidly large number (perhaps equal to the conversation timeout)?

                      Thanks,

                      Damian.



                      • 23. Re: Problems using ajax validation in seam-gen
                        pmuir

                         

                        "vincent.latombe" wrote:
                        And does this timeout represents the amount of time the call must wait before failing, or is it the amount of time we estimate this call should take?


                        IMO These two metrics aren't independent. I think the timeout needs to be set to n * timeout + m, where n & m need to be determined through experiment. In essence I think the timeout needs to be set to somewhat longer than the expected time the method will take to execute.

                        "vincent.latombe" wrote:
                        I think the second option is better. A method should declare how much time it typically takes to execute, so that if a new call occurs, it can wait for this time. By extension, if we have n calls waiting and we've got a n+1-th call coming, this new call must take into consideration all timeouts defined by previous calls and sum them up, to determine the amount of time it should wait.


                        Ok, interesting. I'm not entirely sure I see the benefit of this as it doesn't cancel requests that are taking too long to execute. I can see two scenarios:

                        1) We have the same method (e.g. Damien's example of a total being calculated) for which it doesn't matter if it isn't called every being called many many times. In this case I would think something like:

                        Request 1 -> getTotal is processed for > concurrentRequestTimeout
                        Request 2 -> gets dropped
                        Request 3 -> gets processed
                        Request 4 -> gets dropped
                        Request 5 -> gets dropped
                        Request 6 -> gets processd

                        would be ideal - just some of the requests are processed (this is what currently happens)

                        2) We have a method which we must execute every time. In this case executing the method asynchronously and polling for a result from the page would be a better approach IMO.

                        "pete.muir@jboss.org" wrote:
                        4) Make it easier to disable the warning message on a per request basis - it really means one thing if your conversation times out as you were idle (in this case you want something like "Sorry, you were idle too long and your workspace has been lost") and something completely different if you have a concurrent request timeout ("Sorry, you are swamping the server, please slow down!")

                        That would be a plus, but it shouldn't be necessary if the timeout handling works correctly


                        Ok, but I don't think we're ever going to reach a magic point where this just works ootb (short of just serializing all requests into a queue of infinite length with no timeouts). And even when you're concurrent requests working nicely, you may still have some outside factor (e.g. server has heavy load from another process) which causes your concurrent calls to not be executed within the timeout and you may or may not want to notify the user of this.

                        "damienharvey" wrote:
                        As you say in option 3, something like ignoreDupRequests would be handy, but sometimes you may well want the behaviour that Vincent has coded - ie. I want all of my requests to be processed eventually (within reason). Mind you I suppose that could be accomplished with a very long timeout...


                        Yes, exactly.

                        "damienharvey" wrote:
                        What are the downsides of increasing this timeout? For instance what is the danger in setting it to a stupidly large number (perhaps equal to the conversation timeout)?


                        That if you have a very long running method that is called many times by ajax it may consume much of your processing power, and not timeout. This is why I think you need a sensible default, with the option of increasing it on a per method basis.

                        When the period times out it doesn't just abort the call, it ends the conversation . If you compare a Conversation to a Session, you wouldn't expect a Session to expire just because a page couldn't load.


                        AFAICS it doesn't *end* the conversation, it just kicks you out of it and into another (temporary) conversation - so the previous conversation is still there, but not active. I agree, this isn't very friendly.

                        • 24. Re: Problems using ajax validation in seam-gen

                          Just to rebound on 1), currently if a request gets dropped it kicks you out of the conversation and you get redirected... This redirection should not happen for it to appear as normal behaviour.
                          Another issue is that dropping is ok if it's the same method called, but it's not if it's different call (like different fields in a form just like in the example)

                          So, to summarize things, I think we need :
                          - something equivalent to ignoreDupRequests, as damian said
                          - some way to specify if we want to timeout, or wait indefinitely for our method call to be processed
                          - some way to just drop the call instead of getting an exception and get redirected to the faces messages and kicked out of the conversation.

                          • 25. Re: Problems using ajax validation in seam-gen
                            pmuir

                            Damien, removing the ignoreDupRequests attribute from a:support makes our test case work - this is actually seriously breaking Seam's conversation handling currently as it attempts to abort the current request and sends the next. Unfortunately request isn't aborted. I'll look into why.

                            I've added some docs

                            http://fisheye.jboss.org/browse/JBoss/jboss-seam/doc/reference/en/modules/conversations.xml?r1=1.34&r2=1.35

                            I'll look at the onblur/submit case next.

                            • 26. Re: Problems using ajax validation in seam-gen
                              pmuir

                              Vincent, I've managed to work around the onblur/submit problem like this:

                              <s:decorate id="thirdDecoration" template="layout/edit.xhtml">
                               <ui:define name="label">Third</ui:define>
                               <h:inputText id="third"
                               required="true"
                               value="#{calcBean.third}">
                               <a:support event="onblur" reRender="thirdDecoration, total" eventsQueue="calc" />
                               </h:inputText>
                              </s:decorate>
                              
                              <a:commandButton action="#{calcBean.save}" eventsQueue="calc" value="Save" />


                              (key points are altering the commandButton to be a: rather than h: and using the same queue for all inputs and for the commandButton).

                              Please let me know how this works out for you. If you find it works well I'll look at altering seam-gen to do something similar.

                              Thanks!

                              • 27. Re: Problems using ajax validation in seam-gen

                                I'm a bit late to this party, but we have been experiencing this for months. We originally tried the same technique Pete suggested using - a4j eventqueues with requestDelays - but it didn't go far enough.

                                What we wanted was if a user was typing or clicking, to send one request to the queue requestDelay milliseconds after the final generated event on that queue. This would allow a user to click a button repeatedly, but only the very last button click would be processed. Or if a user went trigger happy on the keyboard in an input field with a keypress event, it would only react on the last keypress event. Or we could send an input field onchange and a button click through the queue to send only the last event. There is a chance for lost javascript events, but since 99.9% of our pages simply submit the form and kick off an action, ignoring the original events didn't really hurt anything.

                                In order to do this we implemented a special JavaScript event queue widget that enforced this behavior. It worked pretty well. However, we still get the "Conversation ended, timed out or was processing another request" message so often that our users consistently bring it up as a problem. We would still love to see JBSEAM-1832 implemented since it helps to address the double click problem as well as the ""The conversation ended, timed out or was processing another request" problem.



                                • 28. Re: Problems using ajax validation in seam-gen

                                  Pete, it seems your workaround is ok, at least it works for me.

                                  1 2 Previous Next