Search in sources :

Example 1 with ExecutorChunk

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

the class BackFiller method makeTentativePlan.

private TentativePlan makeTentativePlan(BuildableItem bi) {
    if (recursion)
        return null;
    recursion = true;
    try {
        // pretend for now that all executors are available and decide some assignment that's executable.
        List<PseudoExecutorSlot> slots = new ArrayList<PseudoExecutorSlot>();
        for (Computer c : Hudson.getInstance().getComputers()) {
            if (c.isOffline())
                continue;
            for (Executor e : c.getExecutors()) {
                slots.add(new PseudoExecutorSlot(e));
            }
        }
        // also ignore all load predictions as we just want to figure out some executable assignment
        // and we are not trying to figure out if this task is executable right now.
        MappingWorksheet worksheet = new MappingWorksheet(bi, slots, Collections.<LoadPredictor>emptyList());
        Mapping m = Hudson.getInstance().getQueue().getLoadBalancer().map(bi.task, worksheet);
        if (m == null)
            return null;
        // figure out how many executors we need on each computer?
        Map<Computer, Integer> footprint = new HashMap<Computer, Integer>();
        for (Entry<WorkChunk, ExecutorChunk> e : m.toMap().entrySet()) {
            Computer c = e.getValue().computer;
            Integer v = footprint.get(c);
            if (v == null)
                v = 0;
            v += e.getKey().size();
            footprint.put(c, v);
        }
        // the point of a tentative plan is to displace other jobs to create a point in time
        // where this task can start executing. An incorrectly estimated duration is not
        // a problem in this regard, as we just need enough idle executors in the right moment.
        // The downside of guessing the duration wrong is that we can end up creating tentative plans
        // afterward that may be incorrect, but those plans will be rebuilt.
        long d = bi.task.getEstimatedDuration();
        if (d <= 0)
            d = TimeUnit2.MINUTES.toMillis(5);
        TimeRange slot = new TimeRange(System.currentTimeMillis(), d);
        // start executing this guy.
        for (Entry<Computer, Integer> e : footprint.entrySet()) {
            Computer computer = e.getKey();
            Timeline timeline = new Timeline();
            for (LoadPredictor lp : LoadPredictor.all()) {
                for (FutureLoad fl : Iterables.limit(lp.predict(worksheet, computer, slot.start, slot.end), 100)) {
                    timeline.insert(fl.startTime, fl.startTime + fl.duration, fl.numExecutors);
                }
            }
            Long x = timeline.fit(slot.start, slot.duration, computer.countExecutors() - e.getValue());
            // if no suitable range was found in [slot.start,slot.end), slot.end would be a good approximation
            if (x == null)
                x = slot.end;
            slot = slot.shiftTo(x);
        }
        TentativePlan tp = new TentativePlan(footprint, slot);
        bi.addAction(tp);
        return tp;
    } finally {
        recursion = false;
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Mapping(hudson.model.queue.MappingWorksheet.Mapping) Executor(hudson.model.Executor) Computer(hudson.model.Computer) ExecutorChunk(hudson.model.queue.MappingWorksheet.ExecutorChunk) WorkChunk(hudson.model.queue.MappingWorksheet.WorkChunk)

Aggregations

Computer (hudson.model.Computer)1 Executor (hudson.model.Executor)1 ExecutorChunk (hudson.model.queue.MappingWorksheet.ExecutorChunk)1 Mapping (hudson.model.queue.MappingWorksheet.Mapping)1 WorkChunk (hudson.model.queue.MappingWorksheet.WorkChunk)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1