0 Replies Latest reply on Aug 22, 2007 10:44 PM by Paul Pantages

    Serializing a4j:poll and form submits

    Paul Pantages Novice

      I am using Seam 1.2.1.GA with Ajax 1.1.1 (provided with the Seam Distribution). I have been having miserable time with assorted errors, like "Can't find stateful bean", null pointers in Conversation.flush(), "No long running conversation" etc.

      I have concluded that at least some of these problems are due to a race condition between my a4j:poll and the "apply/cancel" buttons I have on assorted "editor" pages. Basically, when the operator applies or cancels an "edit", I sometimes get an error when the poller, simutaneously, fires and tries to get its renderList (see below).

      I am guessing that this happens just as Seam is cleaning up my nested conversation, and deleting the beans, as it should when I use @End(beforeRedirect=true) on the apply method.

      What I want to try and do, is, syncrhonize the ajax submissions for a4j:poll and say a4j:commandButton, so that they do not occur in parallel. Perhaps by combining the events into some sort of queue, to ensure that the button press was not submitted until the poll is done and vice versa. My reading of the docs make me think that the eventsQueu would not work for this because my poll and commandButton do not share the same "eventType".

      I wanted to use onsubmit/oncomplete on my a4j:poll to set some sort of flag, but I see that onsubmit still does not work on a4j:poll, despite a JIRA that says it is fixed. (I downloaded the latest 1.1.1 but no go). I managed to scrape up a flag using the enclosing h:form for the onsubmit, and a4j:poll for oncomplete. My apply button as an onclick function that checks the flag and vetoes the submit if the flag is set.

      I found that the the behviour improved when I did this: No more errors, but occasionally the user has to press the button twice, due to the veto.

      My pollers look like so. The errors typically occur when the poller accesses the #{entity} object to get the renderList. The polldone()/pollstart() just set a flag that can be checked by my h:commandButton to see if a poll is in progress.

      
      <h:form onsubmit="return pollStart()">
      ...
      ...
      
      <a4j:region renderRegionOnly="false">
       <a4j:poll
       id="poller"
       interval="#{entity.ajaxPollInterval}"
       enabled="true"
       oncomplete="polldone()"
       eventsQueue="pollerQueue"
       reRender="#{entity.ajaxRenderList}">
       </a4j:poll>
      </a4j:region>
      


      One of my buttons looks like so. PollCheck() will veto the submit if a poll is active.
      <h:commandButton
       value="Apply"
       class="button"
       onmouseover="this.className='buttonUp'"
       onmouseout="this.className='button'"
       onmousedown="this.className='buttonDown'"
       onmouseup="this.className='buttonUp'"
       onclick="return pollCheck();"
       action="#{entity.apply}">
       <s:conversationId/>
      </h:commandButton>
      


      This is not optimal (pressing the button twice) and I am also unsure if it is a very robust fix. If the poll came in "just after" the button press, I think I sill might have a problem, although I have not seen this in the short while I have been testing my flags. I will also have to make sure that I don't lock up the page by killing the poll somehow with the pollFlag "true".

      I think some sort of synchronization or commandQueue would be much better.

      I am not much of an a4j or javascript expert....

      Any help would be much appreciated. Does anyone have any ideas or suggestions?

      PdP