예제 #1
0
  protected <T> Task<T> submitNewTask(final Map flags, final Task<T> task) {
    if (task instanceof ScheduledTask) return submitNewScheduledTask(flags, (ScheduledTask) task);

    totalTaskCount.incrementAndGet();

    beforeSubmit(flags, task);

    if (((BasicTask) task).job == null)
      throw new NullPointerException(
          "Task " + task + " submitted with with null job: job must be supplied.");

    Callable job =
        new Callable() {
          public Object call() {
            Object result = null;
            Throwable error = null;
            String oldThreadName = Thread.currentThread().getName();
            try {
              if (RENAME_THREADS) {
                String newThreadName =
                    oldThreadName
                        + "-"
                        + task.getDisplayName()
                        + "["
                        + task.getId().substring(0, 8)
                        + "]";
                Thread.currentThread().setName(newThreadName);
              }
              beforeStart(flags, task);
              if (!task.isCancelled()) {
                result = ((BasicTask) task).job.call();
              } else throw new CancellationException();
            } catch (Throwable e) {
              error = e;
            } finally {
              if (RENAME_THREADS) {
                Thread.currentThread().setName(oldThreadName);
              }
              afterEnd(flags, task);
            }
            if (error != null) {
              log.warn(
                  "Error while running task " + task + " (rethrowing): " + error.getMessage(),
                  error);
              throw Throwables.propagate(error);
            }
            return result;
          }
        };
    ((BasicTask) task).initExecutionManager(this);

    // If there's a scheduler then use that; otherwise execute it directly
    Set<TaskScheduler> schedulers = null;
    for (Object tago : ((BasicTask) task).tags) {
      TaskScheduler scheduler = getTaskSchedulerForTag(tago);
      if (scheduler != null) {
        if (schedulers == null) schedulers = new LinkedHashSet(2);
        schedulers.add(scheduler);
      }
    }
    Future future;
    if (schedulers != null && !schedulers.isEmpty()) {
      if (schedulers.size() > 1)
        log.warn(
            "multiple schedulers detected, using only the first, for " + task + ": " + schedulers);
      future = schedulers.iterator().next().submit(job);
    } else {
      future = runner.submit(job);
    }

    ((BasicTask) task).initResult(future);
    return task;
  }
  @SuppressWarnings("unchecked")
  protected <T> Task<T> submitNewTask(final Map<?, ?> flags, final Task<T> task) {
    if (task instanceof ScheduledTask)
      return (Task<T>) submitNewScheduledTask(flags, (ScheduledTask) task);

    tasksById.put(task.getId(), task);
    totalTaskCount.incrementAndGet();

    beforeSubmit(flags, task);

    if (((TaskInternal<T>) task).getJob() == null)
      throw new NullPointerException(
          "Task " + task + " submitted with with null job: job must be supplied.");

    Callable<T> job =
        new Callable<T>() {
          public T call() {
            try {
              T result = null;
              Throwable error = null;
              String oldThreadName = Thread.currentThread().getName();
              try {
                if (RENAME_THREADS) {
                  String newThreadName =
                      oldThreadName
                          + "-"
                          + task.getDisplayName()
                          + "["
                          + task.getId().substring(0, 8)
                          + "]";
                  Thread.currentThread().setName(newThreadName);
                }
                beforeStart(flags, task);
                if (!task.isCancelled()) {
                  result = ((TaskInternal<T>) task).getJob().call();
                } else throw new CancellationException();
              } catch (Throwable e) {
                error = e;
              } finally {
                if (RENAME_THREADS) {
                  Thread.currentThread().setName(oldThreadName);
                }
                afterEnd(flags, task);
              }
              if (error != null) {
                if (log.isDebugEnabled()) {
                  // debug only here, because we rethrow
                  log.debug(
                      "Exception running task " + task + " (rethrowing): " + error.getMessage(),
                      error);
                  if (log.isTraceEnabled())
                    log.trace(
                        "Trace for exception running task "
                            + task
                            + " (rethrowing): "
                            + error.getMessage(),
                        error);
                }
                throw Exceptions.propagate(error);
              }
              return result;
            } finally {
              ((TaskInternal<?>) task).runListeners();
            }
          }
        };

    // If there's a scheduler then use that; otherwise execute it directly
    Set<TaskScheduler> schedulers = null;
    for (Object tago : task.getTags()) {
      TaskScheduler scheduler = getTaskSchedulerForTag(tago);
      if (scheduler != null) {
        if (schedulers == null) schedulers = new LinkedHashSet<TaskScheduler>(2);
        schedulers.add(scheduler);
      }
    }
    Future<T> future;
    if (schedulers != null && !schedulers.isEmpty()) {
      if (schedulers.size() > 1)
        log.warn(
            "multiple schedulers detected, using only the first, for " + task + ": " + schedulers);
      future = schedulers.iterator().next().submit(job);
    } else {
      future = runner.submit(job);
    }
    // on completion, listeners get triggered above; here, below we ensure they get triggered on
    // cancel
    // (and we make sure the same ExecutionList is used in the future as in the task)
    ListenableFuture<T> listenableFuture =
        new ListenableForwardingFuture<T>(future, ((TaskInternal<T>) task).getListeners()) {
          @Override
          public boolean cancel(boolean mayInterruptIfRunning) {
            boolean result = false;
            if (!task.isCancelled()) result |= task.cancel(mayInterruptIfRunning);
            result |= super.cancel(mayInterruptIfRunning);
            ((TaskInternal<?>) task).runListeners();
            return result;
          }
        };

    ((TaskInternal<T>) task).initResult(listenableFuture);
    return task;
  }