Search in sources :

Example 1 with WorkUnitContext

use of hudson.model.queue.WorkUnitContext in project hudson-2.x by hudson.

the class Queue method pop.

/**
 * Called by the executor to fetch something to build next.
 * <p>
 * This method blocks until a next project becomes buildable.
 */
public synchronized WorkUnit pop() throws InterruptedException {
    final Executor exec = Executor.currentExecutor();
    if (exec instanceof OneOffExecutor) {
        OneOffExecutor ooe = (OneOffExecutor) exec;
        final WorkUnit wu = ooe.getWorkUnit();
        pendings.remove(wu.context.item);
        return wu;
    }
    try {
        while (true) {
            final JobOffer offer = new JobOffer(exec);
            long sleep = -1;
            // consider myself parked
            assert !parked.containsKey(exec);
            parked.put(exec, offer);
            // reuse executor thread to do a queue maintenance.
            // at the end of this we get all the buildable jobs
            // in the buildables field.
            maintain();
            // allocate buildable jobs to executors
            Iterator<BuildableItem> itr = buildables.iterator();
            while (itr.hasNext()) {
                BuildableItem p = itr.next();
                // one last check to make sure this build is not blocked.
                if (isBuildBlocked(p.task)) {
                    itr.remove();
                    blockedProjects.put(p.task, new BlockedItem(p));
                    continue;
                }
                List<JobOffer> candidates = new ArrayList<JobOffer>(parked.size());
                for (JobOffer j : parked.values()) if (j.canTake(p.task))
                    candidates.add(j);
                MappingWorksheet ws = new MappingWorksheet(p, candidates);
                Mapping m = loadBalancer.map(p.task, ws);
                if (m == null)
                    // check if we can execute other projects
                    continue;
                // found a matching executor. use it.
                WorkUnitContext wuc = new WorkUnitContext(p);
                m.execute(wuc);
                itr.remove();
                if (!wuc.getWorkUnits().isEmpty())
                    pendings.add(p);
            }
            if (!waitingList.isEmpty()) {
                // wait until the first item in the queue is due
                sleep = peek().timestamp.getTimeInMillis() - new GregorianCalendar().getTimeInMillis();
                // avoid wait(0)
                if (sleep < 100)
                    sleep = 100;
            }
            if (sleep == -1)
                offer.event.block();
            else
                offer.event.block(sleep);
            // retract the offer object
            assert parked.get(exec) == offer;
            parked.remove(exec);
            // am I woken up because I have a project to build?
            if (offer.workUnit != null) {
                // if so, just build it
                LOGGER.fine("Pop returning " + offer.workUnit + " for " + exec.getName());
                // TODO: I think this has to be done by the last executor that leaves the pop(), not by main executor
                if (offer.workUnit.isMainWork())
                    pendings.remove(offer.workUnit.context.item);
                return offer.workUnit;
            }
        // otherwise run a queue maintenance
        }
    } finally {
        // remove myself from the parked list
        JobOffer offer = parked.remove(exec);
        if (offer != null && offer.workUnit != null) {
            // we are already assigned a project, but now we can't handle it.
            offer.workUnit.context.abort(new AbortException());
        }
        // since this executor might have been chosen for
        // maintenance, schedule another one. Worst case
        // we'll just run a pointless maintenance, and that's
        // fine.
        scheduleMaintenance();
    }
}
Also used : WorkUnitContext(hudson.model.queue.WorkUnitContext) ArrayList(java.util.ArrayList) GregorianCalendar(java.util.GregorianCalendar) Mapping(hudson.model.queue.MappingWorksheet.Mapping) MappingWorksheet(hudson.model.queue.MappingWorksheet) WorkUnit(hudson.model.queue.WorkUnit) AbortException(hudson.AbortException)

Aggregations

AbortException (hudson.AbortException)1 MappingWorksheet (hudson.model.queue.MappingWorksheet)1 Mapping (hudson.model.queue.MappingWorksheet.Mapping)1 WorkUnit (hudson.model.queue.WorkUnit)1 WorkUnitContext (hudson.model.queue.WorkUnitContext)1 ArrayList (java.util.ArrayList)1 GregorianCalendar (java.util.GregorianCalendar)1