use of hudson.model.queue.MappingWorksheet.WorkChunk 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;
}
}
Aggregations