Exemplo n.º 1
0
 /**
  * Cancels the item in the queue. If the item is scheduled more than once, cancels the first
  * occurrence.
  *
  * @return true if the project was indeed in the queue and was removed. false if this was no-op.
  */
 public synchronized boolean cancel(Task p) {
   LOGGER.fine("Cancelling " + p.getFullDisplayName());
   for (Iterator<WaitingItem> itr = waitingList.iterator(); itr.hasNext(); ) {
     Item item = itr.next();
     if (item.task.equals(p)) {
       itr.remove();
       item.onCancelled();
       return true;
     }
   }
   // use bitwise-OR to make sure that both branches get evaluated all the time
   return blockedProjects.cancel(p) != null | buildables.cancel(p) != null;
 }
Exemplo n.º 2
0
  /**
   * Queue maintenance.
   *
   * <p>Move projects between {@link #waitingList}, {@link #blockedProjects}, and {@link
   * #buildables} appropriately.
   */
  public synchronized void maintain() {
    if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("Queue maintenance started " + this);

    Iterator<BlockedItem> itr = blockedProjects.values().iterator();
    while (itr.hasNext()) {
      BlockedItem p = itr.next();
      if (!isBuildBlocked(p.task)) {
        // ready to be executed
        LOGGER.fine(p.task.getFullDisplayName() + " no longer blocked");
        itr.remove();
        makeBuildable(new BuildableItem(p));
      }
    }

    while (!waitingList.isEmpty()) {
      WaitingItem top = peek();

      if (!top.timestamp.before(new GregorianCalendar()))
        return; // finished moving all ready items from queue

      waitingList.remove(top);
      Task p = top.task;
      if (!isBuildBlocked(p)) {
        // ready to be executed immediately
        LOGGER.fine(p.getFullDisplayName() + " ready to build");
        makeBuildable(new BuildableItem(top));
      } else {
        // this can't be built now because another build is in progress
        // set this project aside.
        LOGGER.fine(p.getFullDisplayName() + " is blocked");
        blockedProjects.put(p, new BlockedItem(top));
      }
    }

    if (sortingHandler != null) sortingHandler.sortBuildableItems(buildables);
  }
Exemplo n.º 3
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;
  }