1 Reply Latest reply on Mar 18, 2009 7:05 PM by grundor

    Fun with ConcurrentRequestTimeoutException

      My applications have been plagued with ConcurrentRequestTimeoutException stacktraces. The stacktraces are illuminated with the information that concurrent calls to conversations are not supported. Because I wasn't aware of any such access, it was just frustrating. Finally, I figured out how I was invoking such calls.

      I've done lot's of GUIs using lots of different frameworks. One of the things I like to do is to let my users know when buttons are really "live" by enabling and disabling them in reesponse to user actions. I'm using RichFaces with lots of a4j:support in my xhtml code.

      Typically, my code would include stuff like:

                  <s:decorate id="appNameField" template="layout/edit.xhtml">
                      <ui:define name="label">App name (unique)</ui:define>
                      <h:inputText id="appName"
                             disabled="#{ssoApplicationHome.managed}"
                             required="true"
                                 size="20"
                            maxlength="20"
                                value="#{ssoApplicationHome.instance.appName}">
                          <a:support event="onchange"
                               reRender="appNameField,actionButtons,saveTip"
                               bypassUpdates="false" ajaxSingle="false"/>
                          <a:support event="onkeyup"
                               reRender="actionButtons,saveTip"
                               bypassUpdates="false" ajaxSingle="false"/>
                          <a:support event="onclick"
                               reRender="actionButtons,saveTip"
                               bypassUpdates="false" ajaxSingle="false"/>
                      </h:inputText>
                  </s:decorate>
                 
               <s:decorate id="saveTip" template="layout/display.xhtml">
                   <ui:define name="label">Save status</ui:define>
                   <h:outputText value="#{ssoApplicationHome.saveTip}">
                   </h:outputText>
               </s:decorate>

      and

                  <rich:panel id="actionButtons" styleClass="dtss2-clear-panel">
                  <h:commandButton id="save"
                                value="Save"
                               action="#{ssoApplicationHome.persist}"
                             disabled="#{!ssoApplicationHome.saveOk}"
                             rendered="#{!ssoApplicationHome.managed}">
                  </h:commandButton>
                 
                  (more buttons here with render and disable conditions....)

           </rich:panel>

      The a4j:support events try to catch most of the changes to the application name so I can update the satus of save and my other buttons. (Unfortunately, the result of a browser-based paste operation doesn't seem to generate an event I can use. I have to wait for the user to leave the field, triggering the onchange event.)

      In other frameworks, I like to display the first reason a Save cannot be done if the user hovers over the disabled Save button. I haven't figured out an easy way to display a tooltip with a disabled button here.

      The application was noticing ConcurrentRequestTimeoutExceptions when I typed into the application name field. I began to suspect a problem evaluating the EL code for disabled and rendered settings on my buttons. I added code to my SessionPrefs class so I could display EL calls. (SessionPrefs is my @Startup class that contains Session settings for the user. Mostly, it contains preferences set at the start of the session.)

      The code is:
           
           // this method may be used to print a message from xhtml by invoking it
           // insert a test like:
           //           rendered="#{sessionPrefs.trueMsg('save rendered') and !ssoApplicationHome.managed}"
           public boolean trueMsg(String msg)
           {
                System.out.println("trueMsg " + msg);
                return true;
           }

      Because it returns a "true" value, it can be added harmlessly to EL code in the xhtml. I was able to confirm what was happening. I've been more careful about side effects from rerender operations.

      I've also added requestDelay to a4j:support for onkeyup events. This means that the code is not necessarily called for each key the user enters. Instead, it is called when a key is pressed and the specified time (msec) elapses, discarding extra changes. Now I've got:

                          <a:support event="onkeyup"
                               reRender="actionButtons,saveTip"
                               requestDelay="100"
                               bypassUpdates="false" ajaxSingle="false"/>

      and I don't have ConcurrentRequestTimeoutExceptions!
        • 1. Re: Fun with ConcurrentRequestTimeoutException

          Valerie,


          I am having similar fun with ConcurrentRequestTimeoutExceptions.  My code and use cases seem very similar to yours.


          You mentioned that you've been more careful about side effects from rerender operations.  Could you give an example of a side effect you tracked down that was causing one of these Exceptions?  I understand the use of requestDelay in a case where you are responding to an onkeyup event in a text box, but where their other situations/events that were causing your problems?


          In my case I will often see these exceptions after I have left a page and ended a conversation (usually before redirect).


          -Mark