11 Replies Latest reply on Feb 16, 2006 3:51 PM by adrian.brock

    ServiceMBeanSupport and ordering, multiple starts

    genman


      I'm a little bothered by how ServiceMBeanSupport doesn't provide any synchronization guarantees and the fact that startService() may be called twice.

      I've been looking at the code. It seems fairly simple to guarantee "only once" behavior by using a SynchronizedInt.

      At the transition points, you would do simply have to do this:

       protected void jbossInternalStart() throws Exception
       {
      ...
       if (!state.commit(CREATED, STARTING))
       {
       return;
       }
      


      You can also create a matrix/list of the valid transitions rather than try to codify it in so many "if" statements in different methods.

      Any thoughts? I'd like to clean this up if you don't mind.

        • 1. Re: ServiceMBeanSupport and ordering, multiple starts

          Go for it.

          But this state is really only indicative. The real state is held on the ServiceContext where
          checking is done in the ServiceController in synchronized methods

          • 2. Re: ServiceMBeanSupport and ordering, multiple starts
            genman


            Okay, then... maybe I have a bug in my application.

            Or the problem has been already fixed. I think I'm sometimes seeing multiple startService() calls on JBoss 3.2.6RC1.

            BTW, the synchronization in ServiceController seems a bit heavy. I wonder if there wasn't a way to parrelize some of it.

            • 3. Re: ServiceMBeanSupport and ordering, multiple starts
              dimitris

              Shouldn't jbossInternalStart() catch this? This is from 3.2.6RC1 :

               protected void jbossInternalStart() throws Exception
               {
               if (state == STARTING || state == STARTED)
               return;
               ...
              


              I agree we need a more "state machine" type approach.

              There are other places in the codebase this would be useful (e.g. ejb timers) so preferably we could have some generic facility for this.

              • 4. Re: ServiceMBeanSupport and ordering, multiple starts

                 

                "genman" wrote:

                BTW, the synchronization in ServiceController seems a bit heavy. I wonder if there wasn't a way to parrelize some of it.


                I am reminded of the Alan Cox quote:
                "A computer is a state machine. Threads are for people who can't program state machines."
                http://www.ussg.iu.edu/hypermail/linux/kernel/0106.2/0444.html

                • 5. Re: ServiceMBeanSupport and ordering, multiple starts
                  genman


                  Funny. I used to write games too and there was no threading, just a state machine that looked like this:

                  main.c
                  
                  while (true) {
                   switch (main.state):
                   case xxx: foo();
                   case yyy: bar();
                   }
                  }
                  
                  foo.c
                  
                  foo() {
                   switch (foo.state) {
                   }
                  }


                  Anyway, I looked into creating a state machine using something like set/wait sort of primitives, e.g.

                  if (!SynchronizedObject.get().equals(CREATED))
                   create();
                  if (SynchronizedObject.commit(CREATED, STARTING)) {
                   // do starting phase
                   SynchronizedObject.commit(STARTING, STARTED);
                  } else {
                   // already started or can't start
                  }


                  for some reason I don't think this would work.

                  • 6. Re: ServiceMBeanSupport and ordering, multiple starts
                    fabcipriano

                    I think that this make sense:

                    public class FSM {
                     public FSM(State initialState) {...}
                     public int addState(State state){...}
                     addTransition(State start, int transition, State end){...}
                    
                     /** If ok return State or IllegalStateException for illegal states*/
                     public State transition(int transition){...}
                    
                    }
                    


                    public class State {
                     int state; //values: STOPPED, STOPPING, etc etc
                     String stateName; //of course, name of state: Stopped, etc, etc
                     Method action; //reflection method to be executed
                    
                     public void execute(){/*invoke action method*/}
                    }
                    


                    public class ServiceMBeanSupport {
                     protected FSM fsm;
                    
                     public ServiceMBeanSupport() {/*construct FSM with default transitions state etc etc ... can be customized from file ?*/}
                    }
                    


                    This form the responsabilities to validate or invalidate state execute appropriaate state action is form FSM class.
                    Like jBPM but without the complexities of jBPM framework.

                    • 7. Re: ServiceMBeanSupport and ordering, multiple starts
                      starksm64

                      See the classes in the org.jboss.util.state.* of the common module/jboss-common.jar. I doubt we need yet another state machine impl.

                      • 8. Re: ServiceMBeanSupport and ordering, multiple starts
                        fabcipriano

                        You are right. Impl. in org.jboss.util.state.* will make the state machine job well.

                        So I'd like to try play with this approach.

                        • 9. Re: ServiceMBeanSupport and ordering, multiple starts
                          genman


                          I would suggest adding some sychronization in the StateMachine so that two threads can't attempt to transition to START at the same time.

                          Methods such as reset, nextState, getCurrentState could have locks.

                          The ordering issue was the point of my concern to begin with...

                          • 10. Re: ServiceMBeanSupport and ordering, multiple starts
                            dimitris

                            To experiment with this I added (in HEAD) a org.jboss.system.ServiceMBeanState class that uses the common org.jboss.util.state classes to define the ServiceMBean states and initialize a state machine, with what I believe is our current lifecycle model.

                            There is a simple test in org.jboss.test.jmx.test.ServiceMBeanStateMachineUnitTestCase

                            This could be used in ServiceMBeanSupport just for validating the state transitions without changing the current logic a lot.

                            Although I think the full potential of a state machine is realized when you add behaviour to the transitions (so e.g. a when on the REGISTERED state a "create" action actually calls "create()", while a "create" action on the CREATED state is a no-op.

                            The good thing however about state machines is it forces you to reconsider all possible outcomes. Having said that.

                            * Do we allow transitions from the FAILED state?
                            * Are no-op transitions valid, e.g. create -> create ?


                            • 11. Re: ServiceMBeanSupport and ordering, multiple starts

                               

                              "dimitris@jboss.org" wrote:

                              Although I think the full potential of a state machine is realized when you add behaviour to the transitions (so e.g. a when on the REGISTERED state a "create" action actually calls "create()", while a "create" action on the CREATED state is a no-op.


                              Sounds a bit like the dependency component of Microcontainer
                              with ControllerState and ControllerContextActions.
                              Although that only supports a linear state model rather than a full blown state
                              transition graph.