/**
   * Stop Cluster and implement the requirements of {@link
   * org.apache.catalina.util.LifecycleBase#stopInternal()}.
   *
   * @exception LifecycleException if this component detects a fatal error that prevents this
   *     component from being used
   */
  @Override
  protected void stopInternal() throws LifecycleException {

    setState(LifecycleState.STOPPING);

    unregisterMember(channel.getLocalMember(false));
    if (clusterDeployer != null) clusterDeployer.stop();
    this.managers.clear();
    try {
      if (clusterDeployer != null) clusterDeployer.setCluster(null);
      channel.stop(channelStartOptions);
      channel.removeChannelListener(this);
      channel.removeMembershipListener(this);
      this.unregisterClusterValve();
    } catch (Exception x) {
      log.error(sm.getString("simpleTcpCluster.stopUnable"), x);
    }
  }
  /**
   * Execute a periodic task, such as reloading, etc. This method will be invoked inside the
   * classloading context of this container. Unexpected throwables will be caught and logged.
   *
   * @see org.apache.catalina.ha.deploy.FarmWarDeployer#backgroundProcess()
   * @see org.apache.catalina.tribes.group.GroupChannel#heartbeat()
   * @see org.apache.catalina.tribes.group.GroupChannel.HeartbeatThread#run()
   */
  @Override
  public void backgroundProcess() {
    if (clusterDeployer != null) clusterDeployer.backgroundProcess();

    // send a heartbeat through the channel
    if (isHeartbeatBackgroundEnabled() && channel != null) channel.heartbeat();

    // periodic event
    fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);
  }
 protected void checkDefaults() {
   if (clusterListeners.size() == 0) {
     addClusterListener(new ClusterSessionListener());
   }
   if (valves.size() == 0) {
     addValve(new JvmRouteBinderValve());
     addValve(new ReplicationValve());
   }
   if (clusterDeployer != null) clusterDeployer.setCluster(this);
   if (channel == null) channel = new GroupChannel();
   if (channel instanceof GroupChannel && !((GroupChannel) channel).getInterceptors().hasNext()) {
     channel.addInterceptor(new MessageDispatch15Interceptor());
     channel.addInterceptor(new TcpFailureDetector());
   }
 }
  /**
   * Start Cluster and implement the requirements of {@link
   * org.apache.catalina.util.LifecycleBase#startInternal()}.
   *
   * @exception LifecycleException if this component detects a fatal error that prevents this
   *     component from being used
   */
  @Override
  protected void startInternal() throws LifecycleException {

    if (log.isInfoEnabled()) log.info(sm.getString("simpleTcpCluster.start"));

    try {
      checkDefaults();
      registerClusterValve();
      channel.addMembershipListener(this);
      channel.addChannelListener(this);
      channel.start(channelStartOptions);
      if (clusterDeployer != null) clusterDeployer.start();
      registerMember(channel.getLocalMember(false));
    } catch (Exception x) {
      log.error(sm.getString("simpleTcpCluster.startUnable"), x);
      throw new LifecycleException(x);
    }

    setState(LifecycleState.STARTING);
  }