Package org.nebulaframework.grid.cluster.manager.services.jobs.splitaggregate

Source Code of org.nebulaframework.grid.cluster.manager.services.jobs.splitaggregate.SplitAggregateJobManager

/*
* Copyright (C) 2008 Yohan Liyanage.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nebulaframework.grid.cluster.manager.services.jobs.splitaggregate;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nebulaframework.core.job.GridJob;
import org.nebulaframework.core.job.splitaggregate.SplitAggregateGridJob;
import org.nebulaframework.grid.cluster.manager.services.jobs.AbstractJobExecutionManager;
import org.nebulaframework.grid.cluster.manager.services.jobs.GridJobProfile;
import org.nebulaframework.grid.cluster.manager.services.jobs.tracking.GridJobTaskTracker;
import org.nebulaframework.grid.service.event.ServiceEventsSupport;
import org.nebulaframework.grid.service.event.ServiceHookCallback;
import org.nebulaframework.grid.service.message.ServiceMessage;
import org.nebulaframework.grid.service.message.ServiceMessageType;
import org.springframework.beans.factory.annotation.Required;

/**
* Split-Aggregate JobManager, which manages execution of Split-Aggregate Model
* GridJobs. This class holds references to {@code SplitterService} and
* {@code AggregatorService}, which handles the split and aggregate processes,
* and also {@code ResultCollector}s, which are responsible for collecting
* individual results.
*
* @author Yohan Liyanage
* @version 1.0
*/
public class SplitAggregateJobManager extends AbstractJobExecutionManager {

  private static final Log log = LogFactory
      .getLog(SplitAggregateJobManager.class);

  private SplitterService splitter;
  private AggregatorService aggregator;

  // Result Collectors
  private Map<String, ResultCollector> collectors = new HashMap<String, ResultCollector>();

  /**
   * {@inheritDoc}
   * <p>
   * Returns the Class for {@code SplitAggregateGridJob}.
   */
  @SuppressWarnings("unchecked")
  @Override
  public Class<? extends GridJob> getInterface() {
    // Return class for SplitAggregateGridJob
    return SplitAggregateGridJob.class;
  }

  /**
   * Starts given {@code SplitAggregateJob} on the Grid.
   *
   * @param profile
   *            GridJobProfile
   */
  @Override
  public boolean startExecution(final GridJobProfile profile, ClassLoader classLoader) {

    // If valid GridJob Type
    if (profile.getJob() instanceof SplitAggregateGridJob) {

      Thread t = new Thread(new Runnable() {

        @Override
        public void run() {

          // Allow Final Results
          profile.getFuture().setFinalResultSupported(true);

          // Create Task Tracker
          profile.setTaskTracker(GridJobTaskTracker
              .startTracker(profile,
                      SplitAggregateJobManager.this));

          // Start Splitter & Aggregator for GridJob
          splitter.startSplitter(profile);
          aggregator.startAggregator(profile,
                        SplitAggregateJobManager.this);

        }

      });
     
      t.setContextClassLoader(classLoader);
      t.start();
     
      return true;
    } else {
      return false;
    }

  }

  /**
   * Sets the {@code SplitterService} used by the {@code JobExecutionManager}.
   * <p>
   * {@code SplitterService} is responsible for splitting a given
   * {@code GridJob} into {@code GridTask}s which are to be executed
   * remotely.
   * <p>
   * <b>Note : </b>This is a <b>required</b> dependency.
   * <p>
   * <i>Spring Injected</i>
   *
   * @param splitterService
   *            SplitterService for the {@code ClusterJobServiceImpl}
   */
  @Required
  public void setSplitter(SplitterService splitter) {
    this.splitter = splitter;
  }

  /**
   * Returns the {@code AggregatorService} used by the
   * {@code ClusterJobServiceImpl}.
   * <p>
   * {@code AggregatorService} is responsible for collecting results returned
   * by each {@code GridTask} which was executed on a remote node, and to
   * aggregate the results to provide the final result for the {@code GridJob}.
   * <p>
   * <b>Note : </b>This is a <b>required</b> dependency.
   * <p>
   * <i>Spring Injected</i>
   *
   * @param aggregatorService
   *            {@code AggregatorService} for the service
   */
  @Required
  public void setAggregator(AggregatorService aggregator) {
    this.aggregator = aggregator;
  }

  /**
   * Returns the {@code SplitterService} used by the
   * {@code ClusterJobServiceImpl}.
   * <p>
   * {@code SplitterService} is responsible for splitting a given
   * {@code GridJob} into {@code GridTask}s which are to be executed
   * remotely.
   *
   * @return {@code SplitterService} reference.
   */
  public SplitterService getSplitter() {
    return splitter;
  }

  /**
   * Returns the {@code AggregatorService} used by the
   * {@code ClusterJobServiceImpl}.
   * <p>
   * {@code AggregatorService} is responsible for collecting results returned
   * by each {@code GridTask} which was executed on a remote node, and to
   * aggregate the results to provide the final result for the {@code GridJob}.
   *
   * @return {@code AggregatorService} reference.
   */
  public AggregatorService getAggregator() {
    return aggregator;
  }

  /**
   * Adds a {@code ResultCollector} for the given Job, denoted by the jobId.
   *
   * @param jobId
   *            GridJob Id
   * @param collector
   *            ResultCollector
   * @throws IllegalArgumentException
   *             if the specified GridJob is already bound to a
   *             ResultCollector
   */
  public void addResultCollector(final String jobId, ResultCollector collector)
      throws IllegalArgumentException {

    if (!this.collectors.containsKey(jobId)) {

      // Add Collector
      collectors.put(jobId, collector);

      // Create Removal Hook
      ServiceEventsSupport.addServiceHook(new ServiceHookCallback() {

        @Override
        public void onServiceEvent(ServiceMessage message) {
          collectors.remove(jobId);
        }

      }, jobId, ServiceMessageType.JOB_END);
    } else {
      throw new IllegalArgumentException(
          "[Split-Aggregate] Result Collector Registered for Job "
              + jobId);
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean cancel(String jobId) {

    if (collectors.containsKey(jobId)) {
      boolean result = collectors.get(jobId).cancel();

      // Record Cancellation
      if (result) {
        markCanceled(jobId);
      }

      return result;
    } else {

      // If this job was canceled already
      if (isRecentlyCancelled(jobId))
        return true;
      log.warn("[SplitAggregateJobService] Unable to Cancel Job " + jobId
          + " : No Processor Reference");
      return false;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void reEnqueueTask(String jobId, int taskId) {
    try {
      log.debug("[SplitAggregateJobService] Re-enqueing  Task" + jobId
          + "|" + taskId);
      splitter.reEnqueueTask(jobId, taskId);
    } catch (RuntimeException e) {
      log.debug("[SplitAggregateJobService] Unable to Re-enqueue Task "
          + jobId + "|" + taskId, e);
    }
  }

}
TOP

Related Classes of org.nebulaframework.grid.cluster.manager.services.jobs.splitaggregate.SplitAggregateJobManager

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.