[mod_cluster-dev] Enabling mod_cluster by default in AS6

Paul Ferraro paul.ferraro at redhat.com
Mon May 3 12:25:33 EDT 2010


On Sat, 2010-05-01 at 15:55 +0200, Bela Ban wrote:
> 
> Paul Ferraro wrote:
> > 1. If a user deletes mod_cluster.sar from their profile, jbossweb will
> > refuse to start since it has a dependency on the ModClusterListener bean
> > - the configuration of which was just deleted. This is rather annoying.
> 
> Maybe this is a general MC question for smart Ales :-) If we have a 
> dependency on a non-existing bean, can't we just ignore that dependency 
> ? For example, if we read in all the beans at MC startup time, construct 
> a dependency graph and see that the ModClusterListener bean doesn't 
> exist, can't we ignore that dependency ?

I think I've found a better solution.  See below.

> The other question I have for Paul, is why does jbossweb have a 
> dependency on ModClusterListener ? Can't ModClisterListener simply query 
> JBossWeb (if available) for deployed contexts (if that's why it 
> registered as a listener) and then register if needed ?

The only reason it is there is to control startup order (and used to be
needed to control shutdown order, though not anymore).  The current
jbossweb integration (via a server lifecycle listener) requires that
mod_cluster's listener (CatalinaEventHandlerAdapter) exists before the
WebServer starts.

> If we could remove this dependency, we'd have one less thing to worry 
> about (and configure)...

Agreed.

> > a. A potential workaround for this: move the mod_cluster jar and
> > configuration xml within the jbossweb service itself, rather than a
> > separate deploy/mod_cluster.sar. Those profiles that include jbossweb,
> > but do not want to include mod_cluster could include a "dummy"
> > ModClusterListener bean configuration - so the dependency is satisfied.
> 
> Hmm, not really nice though...

Admittedly not ideal...

> > b. Hmm - now that I think of it we may actually be able to drop the
> > jbossweb dependency altogether... 
> 
> 
> YEEEAAAHHH !
> 
> > The reason this dependency exists in
> > the first place is to ensure that mod_cluster sends the necessary
> > DISABLE-APP/STOP-APP/REMOVE-APP mcmp messages prior to shutdown of
> > jbossweb. In my fix for MODCLUSTER-131, mod_cluster's shutdown handling
> > was enhanced to react to the "jboss.tomcat.connectors.stopped" JMX
> > event, emitted prior to stopping the Connectors, which is the first
> > thing jbossweb does during shutdown. If I'm not mistaken, this may
> > ultimately mean that we can finally let mod_cluster depend on jbossweb,
> > and not the other way around.
> 
> That's how it should be (see my comment above) !
> 
> 
> > We still need mod_cluster to start before the WebServer
> 
> Why ? Can't we simply grab the deployed contexts from JBossWeb ? If 
> mod-cluster is started before jbossweb, we'll get the deployed contexts 
> later, once jbossweb has been started. Do we get notifications about 
> when beans have been started ? If so we could listen for 
> jbossweb-started, and *then* grab all contexts...

Right.  Scrap that old idea.  Here's what I think we should do (I spent
this morning validating that this works):

Edit mod_cluster MC config such that it depends on the WebServer bean
and is no longer "On Demand".  e.g.
<bean name="ModClusterListener" class="org.jboss.modcluster.catalina.CatalinaEventHandlerAdapter">
  <constructor>
    <!-- To use the HA singleton version of mod_cluster, change this injection to HAModClusterService -->
    <parameter><inject bean="ModClusterService"/></parameter>
    <parameter><inject bean="JMXKernel" property="mbeanServer"/></parameter>
  </constructor>
  <depends>WebServer</depends>
</bean>

Add a start() MC lifecycle method to CatalinaEventHandlerAdapter that
looks like:

public void start() throws JMException
{
   try
   {
      // If the catalina server is already registered, init/start mod_cluster
      Service[] services = (Service[]) this.mbeanServer.invoke(this.serverObjectName, "findServices", null, null);
      if (services.length > 0)
      {
         Server server = (Server) services[0].getServer();
         if (server instanceof Lifecycle)
         {
            Lifecycle lifecycle = (Lifecycle) server;
            for (LifecycleListener listener: lifecycle.findLifecycleListeners())
            {
               // Test if listener is already registered
               if (listener.equals(this)) return;
            }
            lifecycle.addLifecycleListener(this);               
            if (this.init.compareAndSet(false, true))
            {
               this.init(server);
               if (this.start.compareAndSet(false, true))
               {
                  this.eventHandler.start(new CatalinaServer(server, this.mbeanServer));
               }
            }
         }
      }
   }
   catch (InstanceNotFoundException e)
   {
      // Ignore
   }
}

This requires a small modification to the
MicrocontainerIntegrationLifecycleListener, which will need to delegate
equals(Object) to its non-null delegate listener if the argument is a
LifecycleListener, but not an instanceof MCILL.

So, this essentially does what you described.  There are couple other
advantages:
1. We no longer need to define a <Listener/> in server.xml (closes
MODCLUSTER-20 !!!).
2. We no longer rely on the finicky
MicrocontainerIntegrationLifecycleListener, which requires (so to avoid
a call to JBossWebMicrocontainerBeanLocator.getInstalledBean(...) on
every lifecycle event) that the delegate listener is deployed prior to
the start() of the WebServer service.
3. There is no longer any manual step to enable mod_cluster (e.g.
uncommenting <depends>ModClusterListener</depends>) - the existence of
mod_cluster.sar is enough.
4. It is still compatible with the mod_cluster configuration bundled
with AS 6.0.0.M1-M3.
5. mod_cluster is now hot-deployable, independently of jbossweb.  The
addition of a corresponding stop() that removes the lifecycle listener
will allow mod_cluster to be hot-undeployable.

Thoughts?



More information about the mod_cluster-dev mailing list