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

kz.greetgo.scheduling.Scheduler Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
package kz.greetgo.scheduling;

import java.util.*;

public class Scheduler {

  public long idleSleepTime = 200;

  private final Map pools = new HashMap<>();
  private final Set tasks = new HashSet<>();

  private volatile boolean active = true;

  public Scheduler(Collection tasks, Map pools) {
    if (tasks == null || tasks.size() == 0) throw new IllegalArgumentException("no tasks");
    this.tasks.addAll(tasks);
    if (pools != null) this.pools.putAll(pools);

    for (Task task : tasks) {
      final String poolName = task.getPoolName();
      if (poolName == null) throw new IllegalArgumentException("Task does not have a pool name " + task.infoForError());
      if (!this.pools.containsKey(poolName)) throw new NoPoolWithName(poolName, task);
    }
  }

  private long lastRunOfStopLongWaitingThreads = 0;

  private void makeScheduleStep() {

    for (Task task : tasks) {
      if (task.disabled()) continue;
      if (task.isItTimeToRun()) {
        final String poolName = task.getPoolName();
        pools.get(poolName).runTask(task);
      }
    }

    int minimalMaxThreadWaitingDelayInMillis = 0;

    for (ExecutionPool pool : pools.values()) {
      pool.tryExecuteFromQueue();
      if (pool.maxThreadWaitingDelayInMillis > 0) {
        if (minimalMaxThreadWaitingDelayInMillis == 0
            || minimalMaxThreadWaitingDelayInMillis < pool.maxThreadWaitingDelayInMillis) {
          minimalMaxThreadWaitingDelayInMillis = pool.maxThreadWaitingDelayInMillis;
        }
      }
    }

    if (minimalMaxThreadWaitingDelayInMillis == 0) return;

    if (lastRunOfStopLongWaitingThreads == 0) {
      lastRunOfStopLongWaitingThreads = System.currentTimeMillis();
    } else if (System.currentTimeMillis() - lastRunOfStopLongWaitingThreads > minimalMaxThreadWaitingDelayInMillis) {

      for (ExecutionPool pool : pools.values()) {
        pool.stopLongWaitingThreads();
      }

    }
  }

  public static ThrowableCatcher mainThreadCatch = null;

  private final Runnable runner = new Runnable() {
    @Override
    public void run() {

      for (Task task : tasks) {
        task.schedulerStarted();
      }

      while (active) {

        try {
          makeScheduleStep();
        } catch (Throwable e) {
          if (mainThreadCatch == null) {
            e.printStackTrace();
          } else {
            mainThreadCatch.catchThrowable(e);
          }
        }

        synchronized (sync) {
          try {
            sync.wait(idleSleepTime);
          } catch (InterruptedException ignore) {
          }
        }

      }
    }
  };

  private boolean started = false;

  public void startup(String schedulerMainThreadName) {
    markAsStarted();

    final Thread thread = new Thread(runner);

    if (schedulerMainThreadName != null) {
      thread.setName(schedulerMainThreadName);
    }

    thread.start();
  }

  private void markAsStarted() {
    if (started) throw new IllegalStateException("Scheduler already started");
    started = true;
  }

  public void startup() {
    startup("MAIN_SCHEDULER");
  }

  private final Object sync = new Object();

  public void shutdown() {
    if (!active) return;
    active = false;
    synchronized (sync) {
      sync.notifyAll();
    }

    for (ExecutionPool pool : pools.values()) {
      pool.deactivate();
    }
  }

  public void startupInMyThread() {
    markAsStarted();
    runner.run();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy