-
Notifications
You must be signed in to change notification settings - Fork 695
/
NoDelayProvisionerStrategy.java
72 lines (66 loc) · 3.18 KB
/
NoDelayProvisionerStrategy.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package hudson.plugins.ec2;
import hudson.Extension;
import hudson.model.Label;
import hudson.model.LoadStatistics;
import hudson.slaves.Cloud;
import hudson.slaves.NodeProvisioner;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
/**
* Implementation of {@link NodeProvisioner.Strategy} which will provision a new node immediately as
* a task enter the queue.
* Now that EC2 is billed by the minute, we don't really need to wait before provisioning a new node.
*
* @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
*/
@Extension(ordinal = 100)
public class NoDelayProvisionerStrategy extends NodeProvisioner.Strategy {
private static final Logger LOGGER = Logger.getLogger(NoDelayProvisionerStrategy.class.getName());
@Override
public NodeProvisioner.StrategyDecision apply(NodeProvisioner.StrategyState strategyState) {
final Label label = strategyState.getLabel();
LoadStatistics.LoadStatisticsSnapshot snapshot = strategyState.getSnapshot();
int availableCapacity = snapshot.getAvailableExecutors() // live executors
+ snapshot.getConnectingExecutors() // executors present but not yet connected
+ strategyState
.getPlannedCapacitySnapshot() // capacity added by previous strategies from previous rounds
+ strategyState.getAdditionalPlannedCapacity(); // capacity added by previous strategies _this round_
int currentDemand = snapshot.getQueueLength();
LOGGER.log(
Level.FINE, "Available capacity={0}, currentDemand={1}", new Object[] {availableCapacity, currentDemand
});
if (availableCapacity < currentDemand) {
Jenkins jenkinsInstance = Jenkins.get();
for (Cloud cloud : jenkinsInstance.clouds) {
if (!(cloud instanceof EC2Cloud)) {
continue;
}
if (!cloud.canProvision(label)) {
continue;
}
EC2Cloud ec2 = (EC2Cloud) cloud;
if (!ec2.isNoDelayProvisioning()) {
continue;
}
Collection<NodeProvisioner.PlannedNode> plannedNodes =
cloud.provision(label, currentDemand - availableCapacity);
LOGGER.log(Level.FINE, "Planned {0} new nodes", plannedNodes.size());
strategyState.recordPendingLaunches(plannedNodes);
availableCapacity += plannedNodes.size();
LOGGER.log(Level.FINE, "After provisioning, available capacity={0}, currentDemand={1}", new Object[] {
availableCapacity, currentDemand
});
break;
}
}
if (availableCapacity >= currentDemand) {
LOGGER.log(Level.FINE, "Provisioning completed");
return NodeProvisioner.StrategyDecision.PROVISIONING_COMPLETED;
} else {
LOGGER.log(Level.FINE, "Provisioning not complete, consulting remaining strategies");
return NodeProvisioner.StrategyDecision.CONSULT_REMAINING_STRATEGIES;
}
}
}