[jboss-dev-forums] [Design the new POJO MicroContainer] - Re: Parallel deployments

kabir.khan@jboss.com do-not-reply at jboss.com
Fri Jun 19 11:41:54 EDT 2009


I have something working now, and will try to break it with more tests. Before describing what I am doing, here is an outline of what the controller does in pseudocode. 

* install() and change() both obtain the writeLock, update the ctx's required state and end up in resolveContexts(boolean)

  | void resolveContexts(boolean trace){
  |    boolean resolved = true;
  |    while (resolved){
  |      for (state : each controller state registered in controller){
  |        if (resolveContexts(state, state+1, trace){
  |           resolved = true;
  |           break;
  |        }
  |      }
  |   }  
  | }
  | 
  | boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace){
  |    contexts = all contexts in the fromState that have not yet reached the required state, with dependencies satisfied to move to toState
  |    for (ctx : contexts){
  |      attempt to record the ctx as "installing"
  |      if already installing (i.e. by another thread){
  |         continue;
  |      try{
  |        incrementState(ctx, trace);
  |      }finally{
  |        unrecord the ctx as installing
  |      }
  |    } 
  | }
  | 
  | boolean incrementState(ControllerContext ctx, boolean trace){
  |   confirm state ctx is in and which we want to move it to
  |   try{
  |     unlockWriteLock();
  |     install(ctx, fromState, toState); //This invokes the context actions, i.e. the create(), start() methods
  |     move the context to the appropriate state in the controller
  |     invoke callbacks etc.
  |   }finally{
  |     lockWriteLock();
  |     if (install caused error){
  |       record ctx as failed in ctx and controller
  |       return false;
  |     }
  |   }
  |   return true;
  | }
  | 
So basically, the call to resolveContexts(boolean) tries to increment the state of all contexts that can be moved on. If any contexts can be moved on, and succeed resolveContexts(boolean) starts again and goes on until no more contexts can be moved further.

I have added a wrapper around incrementState() which checks if the ctx is ASYNCHRONOUS. If not, it continues as before. If ASYNCHRONOUS, I record it as belonging to the executor, and then invoke a Runnable task using the executor. 

The "installing" check in resolveContexts, has been upated to skip contexts belonging to the executor to avoid the asynchronous context to be picked up by the wrong thread. 

The runnable task looks something like:

  |    class InstallControllerContextTask implements Runnable
  |    {
  |       ControllerContext context;
  |       boolean trace;
  | 
  |       public InstallControllerContextTask(ControllerContext context, boolean trace)
  |       {
  |          this.context = context;
  |          this.trace = trace;
  |       }
  |       
  |       public void run()
  |       {
  |          lockWrite();
  |          //associate context with my thread
  |          try
  |          {
  |             //Move the given context as far through the states towards context.requiredState() as possible
  |             boolean stateChanged = installMyContext();
  |             
  |             //The given context had its state changed, now install anybody who might have been dependent on it
  |             if (stateChanged)
  |             {
  |                resolveContexts(trace);
  |             }
  |          }
  |          finally
  |          {
  |             //remove association between my context and thread
  |             unlockWrite();
  |          }
  |       }
  |    }
  | 


I am currently testing that:
* N asynchronous contexts with no dependencies are getting installed in their own threads and that they can all be in the same lifecycle at the same time
* If an asynchronous context is installed with a dependency on a normal context, the asynchronous context executes in its own thread and stops when the unsatisfied dependency is needed. The dependency is then deployed, and once satisfied the controller picks up the asynchronous context again, and installs that further. Due to the wrapper around incrementState() the asynchronous context is installed in an executor thread again.
* If a normal context is installed with a dependency on an asynchronous context, the normal context is installed in the calling thread and stops when the unsatisfied dependency is needed. The dependency is then deployed, in an executor thread, and once installed the call to resolveContexts() at the end of the Runnable task installs the normal context. The install of the normal context after the wait for its dependencies happens in the executor thread.

I will add more tests on Monday.


View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4238813#4238813

Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4238813



More information about the jboss-dev-forums mailing list