All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ebay.jetstream.scattergather.TaskMaster Maven / Gradle / Ivy

/*******************************************************************************
 *  Copyright © 2012-2015 eBay Software Foundation
 *  This program is dual licensed under the MIT and Apache 2.0 licenses.
 *  Please see LICENSE for more information.
 *******************************************************************************/
package com.ebay.jetstream.scattergather;

/**
 * TaskMaster is created by the TaskMasterFactory. It provides an interface
 * for user to submit scatter gather tasks and get them executed. Upon 
 * successful execution of the tasks the successfully executed tasks are
 * returned back to the caller. It allows a caller to specify the timeout 
 * duration that it must wait for completing the task.
 * 
 * @author [email protected]
 * 
 */


/**
 * @author shmurthy ([email protected])
 * 
 */


import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicBoolean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class TaskMaster {

  private static final Logger LOGGER = LoggerFactory.getLogger("com.ebay.jetstream.scattergather");
  private final LinkedList m_submittedTaskList = new LinkedList();
  private final LinkedList m_executedTaskList = new LinkedList();
  private TaskExecutor m_executor;
  private final Object m_taskCompletionMonitor = new Object();
  private long m_maxWaitTime = 1000;
  private final AtomicBoolean m_abandonTask = new AtomicBoolean(false);
  
  public void abandonTask() {
    m_abandonTask.set(true);
  }

  /**
   * @param timeout
   * @return
   */
  public LinkedList executeTasks(long timeout) {

    synchronized (m_submittedTaskList) {

      Iterator itr = m_submittedTaskList.iterator();

      while (itr.hasNext()) {

        Task t = itr.next();

        t.setAbandonStatusIndicator(m_abandonTask);

        TaskExecutorRequest ter = new TaskExecutorRequest(this, t);

        try {
          m_executor.execute(ter);
        }
        catch (Exception e) {
          // TODO see how to handle this - if we are here it means we have no more resources left
          // problem is part of the task might be already submitted. What do we do with that
          // we might want to throw an exception at this point or continue with the submitted list
        	
          LOGGER.error( "Failed to execute task due to lack of resources - " + e.getLocalizedMessage());
        }

      }

    }

    long expiryTime = System.currentTimeMillis() + timeout;
    long remainingTime = timeout;
    boolean noTaskExecuted = true;
    boolean maxTimeoutExpired = false;

    while (true) {
      synchronized (m_taskCompletionMonitor) {
        try {
          m_taskCompletionMonitor.wait(remainingTime);
        }
        catch (InterruptedException ie) {
        }
      }
      if (m_executedTaskList.size() > 0) {
        noTaskExecuted = false;
      }
      if (m_submittedTaskList.size() == m_executedTaskList.size())
        break;
      
      remainingTime = expiryTime - System.currentTimeMillis();
      if (maxTimeoutExpired) {
        abandonTask();
        break;
      }
      if (remainingTime <= 0) {
        if (noTaskExecuted) {
          LOGGER.warn( "Timeout Extended by 1 SECOND");
          remainingTime = getMaxWaitTime(); // wait a max of 1 more sec
          maxTimeoutExpired = true;
        }
        else {
          abandonTask();
          break;
        }
      }
    }

    return m_submittedTaskList;
  }

  /**
   * @return the executedTaskList
   */
  public LinkedList getExecutedTaskList() {
    return m_executedTaskList;
  }

  /**
   * @return
   */
  public TaskExecutor getExecutor() {
    return m_executor;
  }

  public long getMaxWaitTime() {
    return m_maxWaitTime;
  }

  /**
   * @return the submittedTaskList
   */
  public LinkedList getSubmittedTaskList() {
    return m_submittedTaskList;
  }

  /**
   * @param executor
   */
  public void setExecutor(TaskExecutor executor) {
    m_executor = executor;
  }

  public void setMaxWaitTime(long maxWaitTime) {
    m_maxWaitTime = maxWaitTime;
  }

  /**
   * @param task
   */
  public void submitTask(Task task) {
    synchronized (m_submittedTaskList) {
      m_submittedTaskList.add(task);
    }

  }

  /**
   * @param task
   */
  public void taskCompleted(Task task) {

    synchronized (m_executedTaskList) {
      task.executed();
      m_executedTaskList.add(task);
    }

    synchronized (m_taskCompletionMonitor) {

      m_taskCompletionMonitor.notifyAll();

    }

  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy