7 Replies Latest reply on Oct 17, 2007 1:39 PM by amashtakov

    conversations, propagations etc ... - need explanation

    amashtakov

      Hi,


      I've started to experiment a bit with seam conversations in order
      to develop some sort of global strategy and patterns, which I'm going to
      use in my application.

      I developed a simple app with 2 pages:

      page1.xhtml

      <s:link value="start" action="#{conversation.begin}"/>
      


      page2.xhtml simply displays #{conversationList} in h:dataTable
      and includes
      ...
      <s:link value="start again" propagation="begin"/>
      


      I performed several tests and noticed the following:

      1. With no code modifications:
      Step 1: clicking on "start" on page1.xhtml starts new conversation
      Step 2: clicking on "start again" on page2.xhml creates new
      conversation too.

      Actually, I expected "java.lang.IllegalStateException: begin() called from
      long-running conversation, try join=true" on step 2, according with
      the documentation.

      2. Changes in page2.xhtml:

      ...
      <s:link value="start again" propagation="join"/>
      


      Step 1: clicking on "start" on page1.xhtml starts new conversation
      Step 2: clicking on "start again" on page2.xhml joins current
      conversation

      Can anyone explain why this happens ? From my point of view
      step#2 in test#1 has to generate exception.

      I'll appreciate a good explanation of seam algorithm/steps, which is/are
      used in order to determine whether the long running conversation is
      active or not.

      Thank you in advance,
      /Alexander



        • 1. Re: conversations, propagations etc ... - need explanation
          amashtakov

          Sorry, in a prev. message the code for page1.xhtml
          should look like this (view attribute was missed by copy/paste):

          <s:link value="start" view="/page2.xhtml" action="#{conversation.begin}"/>
          



          • 2. Re: conversations, propagations etc ... - need explanation

            This does not throw an exception due to the behavior of an s:link. An s:link initiates a GET request which will only capture parameters passed in the query string (nothing is posted). If you look at the URL generated by your s:link you will see something like the following:

            .../page2.seam?conversationPropagation=begin

            As you can see, there is no conversationId included in the URL. This would indicate to Seam that a long-running conversation does not exist so promote the temporary conversation to long-running. This could either be a feature or a bug depending on how you look at it. I could imagine situations where this may be a useful feature, but it could definitely be confusing unless you know the finer details.

            In the case where you use join="true", the s:link will send the conversationId as part of the query string:

            .../page2.seam?conversationId=1&conversationPropagation=join

            Obviously if propagation="join" Seam looks for an existing long-running conversation when rendering the s:link (in contrast to propagation="begin").

            • 3. Re: conversations, propagations etc ... - need explanation
              amashtakov

              Thank you - I've got it.

              Meantime I'm trying to explore org.jboss.seam.core.Manager sourcecode
              in order to get an answer about how seam determines if long conversation
              is active, but with no success (

              Seems that restoreConversation() method looks at "conversationIsLongRunningParameter" in request parameters map, but
              what about the postback ? ....

              I think an answer to such question is a "key" for understanding seam
              conversations.

              Can anyone explain how does it work ?

              • 4. Re: conversations, propagations etc ... - need explanation

                Which version of Seam are you using? conversation-is-long-running-parameter is not included in latest (Seam 2.0.0.CR2) due to the addition of conversation-required.

                The key to understanding conversations is the conversationId sent with the request. The conversationId is maintained along with the view (as you've discovered) and indicates to Seam what the foreground long-running conversation is. This is why the back-button just seems to work. If the user goes back to a previous view, the conversationId will be sent with that view in the request so our conversation context is restored (if it exists otherwise redirect to no-conversation-view-id).

                Feel free to parse the code but the details of how this works should really be transparent if you use the methods of propagation provided i.e. @Begin, s:link, s:conversationPropagation, etc). Understanding the semantics is the key. As long as the appropriate conversationId is sent with the request, your conversation state will be restored.

                Hope that helps.

                • 5. Re: conversations, propagations etc ... - need explanation
                  amashtakov

                   


                  Which version of Seam are you using? conversation-is-long-running-parameter is not included in latest (Seam 2.0.0.CR2) due to the addition of conversation-required.


                  I'm using 1.2.1GA


                  The key to understanding conversations is the conversationId sent with the request. The conversationId is maintained along with the view (as you've discovered) and indicates to Seam what the foreground long-running conversation is.


                  I noticed two GET parameters [cid] and [clr] and it seems that the second
                  one is used in order to check whether the conversation is long running or not. But I do not understand how does the postback work - tried to
                  print out the request parameters but nothing about cid/clr:

                  <c:forEach var="n" items="#{facesContext.externalContext.requestParameterMap}">
                   #{n.key} = #{n.value}<br/>
                  </c:forEach>
                  



                  This is why the back-button just seems to work. If the user goes back to a previous view, the conversationId will be sent with that view in the request so our conversation context is restored (if it exists otherwise redirect to no-conversation-view-id).

                  How does the conversationId sent with that view ?
                  I checked seam-booking demo with back button - the page is restored, but
                  seems it's from browser's cache - server.log didn't included an extra request trace.


                  Understanding the semantics is the key. As long as the appropriate conversationId is sent with the request, your conversation state will be restored.


                  As a GET parameter ?



                  • 6. Re: conversations, propagations etc ... - need explanation

                     

                    "amashtakov" wrote:
                    I'm using 1.2.1GA


                    Yes, 1.2.1.GA uses clr (conversation-long-running-parameter="clr").

                    There are essentially 2 scenarios:

                    - GET - conversation attributes passed in query string (the situation you are referring to)
                    - POST - conversation attributes posted with the form not in the query string (handled transparently by Seam but feel free to parse the code to see the finer details)

                    So if you use an h:commandLink, h:commandButton, etc, a POST will be initiated which will transparently send the values along with the form. Due to this, the browser cached page will include the values along with the form which is why the back button works.

                    • 7. Re: conversations, propagations etc ... - need explanation
                      amashtakov

                      Thank you,
                      I'm going to experiment tomorrow a bit more (do not have jboss/seam at home yet) - will check back button feature.