7 Replies Latest reply on Sep 3, 2007 9:42 AM by galder.zamarreno

    When in the servlet lifecycle does http session state replic

      When in the servlet lifecycle does http session state replication occur when clustering http sessions in JBoss ?

      Does it occur at the beginning & end of any request ? Is there some way to control when the replication occurs ?

      I have a long running operation which changes the http session state. If the server fails-over during this long running request the session data does not seem to have been replicated. The fail-over seems to work correctly the browser maintains it's connection and the code continues to execute on another server but it looses it's session data.

      The following code simulates my problem. This code just starts & stops a countdown that writes to the log. There is a button to dump the http session state to the log.

      Scenario 1:

      1) click start button
      2) kill server it is running on

      What I see is the countdown starts decremeting the count writing a message to the log every 2 seconds. Then when the server is killed the second server picks up the code no problem and start running it. But the countdown starts back at the initial value. I was expecting that it would continue where it left off on the first server.

      Scenario 2:

      1) click start button
      2) click dump button
      3) kill server it is running on

      What I see is the countdown starts decremeting the count writing a message to the log every 2 seconds. Then when the server is killed the second server picks up the code no problem and start running it. The coundown does not start back at the initial value, but but at the value that was printed in the dump step. I was expecting that it would continue where it left off on the first server.

      So it seems that the dump request is triggering the http session replication. Which leads me to my question, what triggers the replication to occur ? and how much control is there over the timing. It does not seem to matter if I use SYNC or ASYNC replicaton as the replication seems to not be triggered.

      I expected initially that the session would replicate everytime it was modified, but that is clearly not the case.

      Thanks in advance for your help.
      Tom


      <%@ page import="org.apache.commons.logging.Log" %>
      <%@ page import="org.apache.commons.logging.LogFactory" %>
      <%@ page import="java.util.Enumeration" %>
      
      <% final Log logger = LogFactory.getLog("JSP Logger"); %>
      
      <html>
      Hit the start button to start the countdown. Hit the stop button to stop the countdown. Hit the dump button to print the http session state.
      <form action="/tlh/tlh.jsp?state=start" method=post>
       <input type=submit value="start">
      </form>
      <form action="/tlh/tlh.jsp?state=stop" method=post>
       <input type=submit value="stop">
      </form>
      <form action="/tlh/tlh.jsp?state=dump" method=post>
       <input type=submit value="dump">
      </form>
      <%
       String state = (String)request.getParameter("state");
       if (state == null) state = "stop";
      
       if (state.equals("dump")) {
       Enumeration enm = session.getAttributeNames();
       while(enm.hasMoreElements()) {
       String attr = (String)enm.nextElement();
       logger.error("*************** TEST SessionID=" + session.getId());
       logger.error("*************** TEST Session variable: " + attr + " value: " + session.getAttribute(attr));
       }
       } else {
       session.setAttribute("state", state);
       if (state.equals("start")) {
       if (session.getAttribute("cnt") == null) {
       session.setAttribute("cnt", new Integer(100000000));
       }
      
       int i = ((Integer)session.getAttribute("cnt")).intValue();
       while (i > 0) {
       logger.error("*************** TEST " + i);
       session.setAttribute("cnt", new Integer(--i));
      
       //Hack seems to make session replicate before end of http request
       Enumeration enm = session.getAttributeNames();
       while(enm.hasMoreElements()) {
       String attr = (String)enm.nextElement();
       session.getAttribute(attr);
       }
      
       Thread.sleep(2000);
       if (((String)session.getAttribute("state")).equals("stop")) break;
       }
       }
       }
      %>
      </html>
      


        • 1. Re: When in the servlet lifecycle does http session state re

          Sorry, had some extraneous code in the example. The block of code commeted "Hack to make the session replicate" should not have been there (it did not make the session replicate). Below is the correct code.

          Thanks,
          Tom




          <%@ page import="org.apache.commons.logging.Log" %>
          <%@ page import="org.apache.commons.logging.LogFactory" %>
          <%@ page import="java.util.Enumeration" %>
          
          <% final Log logger = LogFactory.getLog("JSP Logger"); %>
          
          <html>
          Hit the start button to start the countdown. Hit the stop button to stop the countdown. Hit the dump button to print the http session state.
          <form action="/tlh/tlh.jsp?state=start" method=post>
           <input type=submit value="start">
          </form>
          <form action="/tlh/tlh.jsp?state=stop" method=post>
           <input type=submit value="stop">
          </form>
          <form action="/tlh/tlh.jsp?state=dump" method=post>
           <input type=submit value="dump">
          </form>
          <%
           String state = (String)request.getParameter("state");
           if (state == null) state = "stop";
          
           if (state.equals("dump")) {
           Enumeration enm = session.getAttributeNames();
           while(enm.hasMoreElements()) {
           String attr = (String)enm.nextElement();
           logger.error("*************** TEST SessionID=" + session.getId());
           logger.error("*************** TEST Session variable: " + attr + " value: " + session.getAttribute(attr));
           }
           } else {
           session.setAttribute("state", state);
           if (state.equals("start")) {
           if (session.getAttribute("cnt") == null) {
           session.setAttribute("cnt", new Integer(100000000));
           }
          
           int i = ((Integer)session.getAttribute("cnt")).intValue();
           while (i > 0) {
           logger.error("*************** TEST " + i);
           session.setAttribute("cnt", new Integer(--i));
           Thread.sleep(2000);
           if (((String)session.getAttribute("state")).equals("stop")) break;
           }
           }
           }
          %>
          </html>


          • 2. Re: When in the servlet lifecycle does http session state re
            brian.stansberry

            The session replicates at the end of the request, not as modifications are made. There is currently no way to change this behavior.

            If this is important to you, please raise a feature request in the JBoss Application Server project on jira.jboss.com.

            • 3. Re: When in the servlet lifecycle does http session state re

              Thank you.

              Does it also replicate at the start of a request ? If it replicates at both the start and end of a request that would explain the behavior I've observed.


              Thanks for your help.
              Tom

              • 4. Re: When in the servlet lifecycle does http session state re
                brian.stansberry

                No, it doesn't replicate at the start of the request.

                In releases prior to 4.0.4, calling session.getAttributeNames() would mark the session as dirty, thus causing replication at the end of the request. That's why your "dump" call causes replication. I believe I changed that in 4.0.4.

                I figured out a hack you can try to get immediate replication upon change of an attribute. This may or may not work. You'd need to use 4.0.4, with this in your jboss-web.xml

                <replication-config>
                 <replication-granularity>FIELD</replication-granularity>
                 <replication-trigger>(whatever you want)</replication-trigger>
                 <replicationFieldBatchMode>false</replicationFieldBatchMode>
                </replication-config>
                


                With FIELD granularity and no batching, you'll get immediate replication. You don't need to instrument your classes to use FIELD; you just don't get the benefits of fine-grained replication if you don't.

                • 5. Re: When in the servlet lifecycle does http session state re

                  Thank you. This configuration seems to produce the behavior I was expecting.

                  • 6. Re: When in the servlet lifecycle does http session state re
                    brian.stansberry

                    Cool :) Be sure to test thoroughly. The session is really composed of 2 elements -- the attributes and the metadata (things like lastAccessedTime, id, etc). The metadata is still replicated at the end of the request, so you may get odd behavior.

                    • 7. Re: When in the servlet lifecycle does http session state re
                      galder.zamarreno

                      XML configuration for replicationFieldBatchMode should be replication-field-batch-mode and not replicationFieldBatchMode, i.e.

                      <replication-config>
                       <replication-granularity>FIELD</replication-granularity>
                       <replication-trigger>(whatever you want)</replication-trigger>
                       <replication-field-batch-mode>false</replication-field-batch-mode>
                      </replication-config>