Package org.radargun.stages.distributedtask

Source Code of org.radargun.stages.distributedtask.DistributedTaskStage$TextAck

package org.radargun.stages.distributedtask;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.radargun.DistStageAck;
import org.radargun.StageResult;
import org.radargun.config.Property;
import org.radargun.config.Stage;
import org.radargun.stages.AbstractDistStage;
import org.radargun.state.SlaveState;
import org.radargun.traits.CacheInformation;
import org.radargun.traits.Clustered;
import org.radargun.traits.DistributedTaskExecutor;
import org.radargun.traits.InjectTrait;
import org.radargun.utils.Projections;
import org.radargun.utils.Utils;

/**
* Executes a Callable or DistributedCallable against the cache using the
* DistributedExecutorService. The execution and failover policies can be specified. If the IP
* address of a node is specified in <code>nodeAddress</code>, then the Callable is only executed on
* that node. Public String Fields on the Callable object can be set using the
* <code>distributedExecutionParams</code> property.
*
* @author Alan Field &lt;afield@redhat.com&gt;
*/
@Stage(doc = "Stage which executes a MapReduce Task against all keys in the cache.")
public class DistributedTaskStage<K, V, T> extends AbstractDistStage {

   private final String FIRST_SCALE_STAGE_KEY = "firstScalingStage";

   @Property(optional = false, doc = "Fully qualified class name of the "
         + "org.infinispan.distexec.DistributedCallable or "
         + "java.util.concurrent.Callable implementation to execute.")
   private String distributedCallableFqn;

   @Property(optional = true, doc = "The name of one of the "
         + "org.infinispan.distexec.DistributedTaskExecutionPolicy enums. The default is null.")
   private String executionPolicyName;

   @Property(optional = true, doc = "The fully qualified class name for a custom "
         + "org.infinispan.distexec.DistributedTaskFailoverPolicy implementation. The default is null.")
   private String failoverPolicyFqn = null;

   @Property(optional = true, doc = "The node address where the task will be "
         + "executed. The default is null, and tasks will be executed against all nodes in the cluster.")
   private String nodeAddress = null;

   @Property(optional = true, doc = "A String in the form of "
         + "'methodName:methodParameter;methodName1:methodParameter1' that allows"
         + " invoking a method on the distributedCallableFqn Object. The method"
         + " must be public and take a String parameter.")
   private String distributedExecutionParams = null;

   @InjectTrait(dependency = InjectTrait.Dependency.MANDATORY)
   private DistributedTaskExecutor executor;

   @InjectTrait(dependency = InjectTrait.Dependency.MANDATORY)
   private CacheInformation cacheInformation;

   @InjectTrait(dependency = InjectTrait.Dependency.MANDATORY)
   private Clustered clustered;

   @Override
   public StageResult processAckOnMaster(List<DistStageAck> acks) {
      StageResult result = super.processAckOnMaster(acks);
      StringBuilder reportCsvContent = new StringBuilder();

      // TODO: move this into test report
      if (masterState.get(FIRST_SCALE_STAGE_KEY) == null) {
         masterState.put(FIRST_SCALE_STAGE_KEY, masterState.getConfigName());
         reportCsvContent.append("NODE_INDEX, NUMBER_OF_NODES, KEY_COUNT_ON_NODE, DURATION_NANOSECONDS\n");
      }

      for (TextAck ack : Projections.instancesOf(acks, TextAck.class)) {
         reportCsvContent.append(ack.getText()).append("\n");
      }
      reportCsvContent.append("\n");

      try {
         Utils.createOutputFile("distributedexecution.csv", reportCsvContent.toString(), false);
      } catch (IOException e) {
         log.error("Failed to create report.", e);
      }

      return result;
   }

   @Override
   public DistStageAck executeOnSlave() {
      if (!isServiceRunning()) {
         return errorResponse("Service not running", null);
      }

      if (distributedCallableFqn == null) {
         return errorResponse("The distributed task or callable class must be specified.", null);
      }

      if (slaveState.getSlaveIndex() == 0) {
         return executeTask();
      } else {
         return new TextAck(slaveState);
      }
   }

   private String getPayload(long durationNanos) {
      return slaveState.getSlaveIndex() + ", " + clustered.getClusteredNodes() + ", " + cacheInformation.getCache(null).getLocallyStoredSize() + ", " + durationNanos;
   }

   private DistStageAck executeTask() {
      List<Future<T>> futureList = null;
      List<T> resultList = new ArrayList<T>();

      log.info("--------------------");
      long start = System.nanoTime();
      futureList = executor.executeDistributedTask(distributedCallableFqn,
            executionPolicyName, failoverPolicyFqn, nodeAddress, Utils.parseParams(distributedExecutionParams));
      TextAck ack = new TextAck(slaveState);
      if (futureList == null) {
         ack.error("No future objects returned from executing the distributed task.");
      } else {
         for (Future<T> future : futureList) {
            try {
               resultList.add(future.get());
            } catch (InterruptedException e) {
               ack.error("The distributed task was interrupted.", e);
            } catch (ExecutionException e) {
               ack.error("An error occurred executing the distributed task.", e);
            }
         }
      }
      long durationNanos = System.nanoTime() - start;
      ack.setText(getPayload(durationNanos));

      log.info("Distributed Execution task completed in " + Utils.prettyPrintTime(durationNanos, TimeUnit.NANOSECONDS));
      log.infof("%d nodes were used. %d entries on this node",
            clustered.getClusteredNodes(), cacheInformation.getCache(null).getLocallyStoredSize());
      log.info("Distributed execution results:");
      log.info("--------------------");
      for (T t : resultList) {
         log.info(t.toString());
      }
      log.info("--------------------");
      return ack;
   }

   private static class TextAck extends DistStageAck {
      private String text;

      private TextAck(SlaveState slaveState) {
         super(slaveState);
         this.text = text;
      }

      public void setText(String text) {
         this.text = text;
      }

      public String getText() {
         return text;
      }
   }
}
TOP

Related Classes of org.radargun.stages.distributedtask.DistributedTaskStage$TextAck

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.