Ejemplo n.º 1
0
  /**
   * Schedules an execution of a task.
   *
   * @since 1.311
   * @return null if this task is already in the queue and therefore the add operation was no-op.
   *     Otherwise indicates the {@link WaitingItem} object added, although the nature of the queue
   *     is that such {@link Item} only captures the state of the item at a particular moment, and
   *     by the time you inspect the object, some of its information can be already stale.
   *     <p>That said, one can still look at {@link WaitingItem#future}, {@link WaitingItem#id},
   *     etc.
   */
  private synchronized WaitingItem scheduleInternal(Task p, int quietPeriod, List<Action> actions) {
    WaitingItem added = null;
    List<Item> items = getItems(p);
    Calendar due = new GregorianCalendar();
    due.add(Calendar.SECOND, quietPeriod);

    List<Item> duplicatesInQueue = new ArrayList<Item>();
    for (Item item : items) {
      boolean shouldScheduleItem = false;
      for (Action action : item.getActions()) {
        if (action instanceof QueueAction)
          shouldScheduleItem |= ((QueueAction) action).shouldSchedule(actions);
      }
      for (Action action : actions) {
        if (action instanceof QueueAction) {
          shouldScheduleItem |= ((QueueAction) action).shouldSchedule(item.getActions());
        }
      }
      if (!shouldScheduleItem) {
        duplicatesInQueue.add(item);
      }
    }
    if (duplicatesInQueue.size() == 0) {
      LOGGER.fine(p.getFullDisplayName() + " added to queue");

      // put the item in the queue
      waitingList.add(added = new WaitingItem(due, p, actions));
    } else {
      // the requested build is already queued, so will not be added
      List<WaitingItem> waitingDuplicates = new ArrayList<WaitingItem>();
      for (Item item : duplicatesInQueue) {
        for (Action a : actions) {
          if (a instanceof FoldableAction) {
            ((FoldableAction) a).foldIntoExisting(item.task, item.getActions());
          }
        }
        if ((item instanceof WaitingItem)) waitingDuplicates.add((WaitingItem) item);
      }
      if (duplicatesInQueue.size() == 0) {
        // all duplicates in the queue are already in the blocked or
        // buildable stage no need to requeue
        return null;
      }
      // TODO: avoid calling scheduleMaintenance() if none of the waiting items
      // actually change
      for (WaitingItem wi : waitingDuplicates) {
        if (quietPeriod <= 0) {
          // the user really wants to build now, and they mean NOW.
          // so let's pull in the timestamp if we can.
          if (wi.timestamp.before(due)) continue;
        } else {
          // otherwise we do the normal quiet period implementation
          if (wi.timestamp.after(due)) continue;
          // quiet period timer reset. start the period over again
        }

        // waitingList is sorted, so when we change a timestamp we need to maintain order
        waitingList.remove(wi);
        wi.timestamp = due;
        waitingList.add(wi);
      }
    }
    scheduleMaintenance(); // let an executor know that a new item is in the queue.
    return added;
  }
Ejemplo n.º 2
0
 protected Item(Item item) {
   this(item.task, item.getActions(), item.id, item.future);
 }