Package org.radargun.stages.lifecycle

Source Code of org.radargun.stages.lifecycle.LifecycleHelper$ClusterFormationTimeoutException

package org.radargun.stages.lifecycle;

import java.util.Set;

import org.radargun.logging.Log;
import org.radargun.logging.LogFactory;
import org.radargun.reporting.Timeline;
import org.radargun.state.ServiceListener;
import org.radargun.state.SlaveState;
import org.radargun.traits.Clustered;
import org.radargun.traits.Killable;
import org.radargun.traits.Lifecycle;
import org.radargun.traits.Partitionable;

/**
* Helper class for controlling the lifecycle of a service.
* Assumes that the service has the {@link Lifecycle} trait,
* other traits are optional.
*/
public class LifecycleHelper {

   protected static final String LIFECYCLE = "Lifecycle";

   private LifecycleHelper() {}
  
   private static final Log log = LogFactory.getLog(LifecycleHelper.class);

   /**
    * Starts the service.
    * If the service supports {@link Clustered} trait and {@code validate} is set to true,
    * the method waits until {@link org.radargun.traits.Clustered#getClusteredNodes() clustered trait}
    * reports {@code expectedSlaves} slaves or for {@code clusterFormationTimeout} milliseconds.
    * If the service supports {@link Partitionable} trait, the set of {@code reachable} slaves
    * is set up before the service is started.
    * Also, this method calls the {@link ServiceListener service listeners} on {@link SlaveState}.
    * If the start fails, attempt to stop the service is executed.
    *
    * @param slaveState
    * @param validate
    * @param expectedSlaves
    * @param clusterFormationTimeout
    * @param reachable
    */
   public static void start(SlaveState slaveState, boolean validate, Integer expectedSlaves, long clusterFormationTimeout,
                            Set<Integer> reachable) {
      Lifecycle lifecycle = slaveState.getTrait(Lifecycle.class);
      Clustered clustered = slaveState.getTrait(Clustered.class);
      Partitionable partitionable = slaveState.getTrait(Partitionable.class);
      try {
         if (partitionable != null) {
            partitionable.setStartWithReachable(slaveState.getSlaveIndex(), reachable);
         }
         for (ServiceListener listener : slaveState.getServiceListeners()) {
            listener.beforeServiceStart();
         }
         long startingTime = System.currentTimeMillis();
         lifecycle.start();
         long startedTime = System.currentTimeMillis();
         slaveState.getTimeline().addEvent(LifecycleHelper.LIFECYCLE, new Timeline.IntervalEvent(startingTime, "Start", startedTime - startingTime));
         if (validate && clustered != null) {

            int expectedNumberOfSlaves = expectedSlaves != null ? expectedSlaves : slaveState.getGroupSize();

            long clusterFormationDeadline = System.currentTimeMillis() + clusterFormationTimeout;
            for (;;) {
               int numMembers = clustered.getClusteredNodes();
               if (numMembers != expectedNumberOfSlaves) {
                  String msg = "Number of members=" + numMembers + " is not the one expected: " + expectedNumberOfSlaves;
                  log.info(msg);
                  try {
                     Thread.sleep(1000);
                  } catch (InterruptedException ie) {
                     Thread.currentThread().interrupt();
                  }
                  if (System.currentTimeMillis() > clusterFormationDeadline) {
                     throw new ClusterFormationTimeoutException(msg);
                  }
               } else {
                  log.info("Number of members is the one expected: " + clustered.getClusteredNodes());
                  break;
               }
            }
         }
         for (ServiceListener listener : slaveState.getServiceListeners()) {
            try {
               listener.afterServiceStart();
            } catch (Exception e) {
               log.error("Failed to run listener " + listener, e);
            }
         }
      } catch (RuntimeException e) {
         log.trace("Failed to start", e);
         try {
            lifecycle.stop();
         } catch (Exception ignored) {
            log.trace("Failed to stop after start failed", ignored);
         }
         throw e;
      }
   }

   /**
    * Stops the service.
    * If the service supports the {@link Killable} trait and {@code graceful} is set to false,
    * this trait is used to kill the service instead of stopping it. Also, non-graceful stop
    * can be executed asynchronously using {@link org.radargun.traits.Killable#killAsync()}.
    * This method calls the {@link ServiceListener service listeners} on {@link SlaveState}.
    *
    * @param slaveState
    * @param graceful
    * @param async
    */
   public static void stop(SlaveState slaveState, boolean graceful, boolean async) {
      Lifecycle lifecycle = slaveState.getTrait(Lifecycle.class);
      if (lifecycle == null) throw new IllegalArgumentException();
      Killable killable = slaveState.getTrait(Killable.class);
      if (lifecycle.isRunning()) {
         for (ServiceListener listener : slaveState.getServiceListeners()) {
            listener.beforeServiceStop(graceful);
         }
         try {
            long stoppingTime;
            if (graceful || killable == null) {
               if (async) {
                  log.warn("Async graceful stop is not supported.");
               }
               if (graceful) {
                  log.info("Stopping service.");
               } else {
                  log.info("Service is not Killable, stopping instead");
               }
               stoppingTime = System.currentTimeMillis();
               lifecycle.stop();
            } else {
               log.info("Killing service.");
               stoppingTime = System.currentTimeMillis();
               if (async) {
                  killable.killAsync();
               } else {
                  killable.kill();
               }
            }
            long stoppedTime = System.currentTimeMillis();
            slaveState.getTimeline().addEvent(LIFECYCLE, new Timeline.IntervalEvent(stoppingTime, "Stop", stoppedTime - stoppingTime));
         } finally {
            for (ServiceListener listener : slaveState.getServiceListeners()) {
               listener.afterServiceStop(graceful);
            }
         }
      } else {
         log.info("No cache wrapper deployed on this slave, nothing to do.");
      }
   }

   private static class ClusterFormationTimeoutException extends RuntimeException {
      public ClusterFormationTimeoutException(String msg) {
         super(msg);
      }
   }
}
TOP

Related Classes of org.radargun.stages.lifecycle.LifecycleHelper$ClusterFormationTimeoutException

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.