/*
* The MIT License
*
* Copyright (c) 2010, InfraDNA, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.model.queue;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.model.Computer;
import hudson.model.Executor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Predicts future load to the system, to assist the scheduling decisions
*
* <p>
* When Hudson makes a scheduling decision, Hudson considers predicted future load
* — e.g., "We do currently have one available executor, but we know we need this for something else in 30 minutes,
* so we can't currently schedule a build that takes 1 hour."
*
* <p>
* This extension point plugs in such estimation of future load.
*
* @author Kohsuke Kawaguchi
*/
public abstract class LoadPredictor implements ExtensionPoint {
/**
* Estimates load starting from the 'start' timestamp, up to the 'end' timestamp.
*
* @param start
* Where to start enumeration. Always bigger or equal to the current time of the execution.
* @param plan
* This is the execution plan for which we are making a load prediction. Never null. While
* this object is still being partially constructed when this method is called, some
* of its properties (like {@link MappingWorksheet#item} provide access to more contextual
* information.
* @since 1.380
*/
public Iterable<FutureLoad> predict(MappingWorksheet plan, Computer computer, long start, long end) {
// maintain backward compatibility by calling the old signature.
return predict(computer,start,end);
}
/**
* Estimates load starting from the 'start' timestamp, up to the 'end' timestamp.
*
* @param start
* Where to start enumeration. Always bigger or equal to the current time of the execution.
* @deprecated as of 1.380
* Use {@link #predict(MappingWorksheet, Computer, long, long)}
*/
@Deprecated
public Iterable<FutureLoad> predict(Computer computer, long start, long end) {
return Collections.emptyList();
}
/**
* All the registered instances.
*/
public static ExtensionList<LoadPredictor> all() {
return ExtensionList.lookup(LoadPredictor.class);
}
/**
* Considers currently running tasks and their completion.
*/
@Extension
public static class CurrentlyRunningTasks extends LoadPredictor {
@Override
public Iterable<FutureLoad> predict(MappingWorksheet plan, final Computer computer, long start, long eternity) {
long now = System.currentTimeMillis();
List<FutureLoad> fl = new ArrayList<FutureLoad>();
for (Executor e : computer.getExecutors()) {
if (e.isIdle()) continue;
long eta = e.getEstimatedRemainingTimeMillis();
long end = eta<0 ? eternity : now + eta; // when does this task end?
if (end < start) continue; // should be over by the 'start' time.
fl.add(new FutureLoad(start, end-start, 1));
}
return fl;
}
}
}