@@ -0,0 +1,2862 @@
+package hudson.plugins.ec2;%0A%0Aimport hudson.Extension;%0Aimport hudson.model.Label;%0Aimport hudson.model.LoadStatistics;%0Aimport hudson.slaves.Cloud;%0Aimport hudson.slaves.NodeProvisioner;%0Aimport jenkins.model.Jenkins;%0A%0Aimport java.util.Collection;%0Aimport java.util.logging.Level;%0Aimport java.util.logging.Logger;%0A%0A/**%0A * Implementation of %7B@link NodeProvisioner.Strategy%7D which will provision a new node immediately as%0A * a task enter the queue.%0A * Now that EC2 is billed by the minute, we don't really need to wait before provisioning a new node.%0A *%0A * @author %3Ca href=%22mailto:nicolas.deloof@gmail.com%22%3ENicolas De Loof%3C/a%3E%0A */%0A@Extension(ordinal = 100)%0Apublic class NoDelayProvisionerStrategy extends NodeProvisioner.Strategy %7B%0A%0A    private static final Logger LOGGER = Logger.getLogger(NoDelayProvisionerStrategy.class.getName());%0A%0A    @Override%0A    public NodeProvisioner.StrategyDecision apply(NodeProvisioner.StrategyState strategyState) %7B%0A        final Label label = strategyState.getLabel();%0A%0A        LoadStatistics.LoadStatisticsSnapshot snapshot = strategyState.getSnapshot();%0A        int availableCapacity =%0A                  snapshot.getAvailableExecutors()   // live executors%0A                + snapshot.getConnectingExecutors()  // executors present but not yet connected%0A                + strategyState.getPlannedCapacitySnapshot()     // capacity added by previous strategies from previous rounds%0A                + strategyState.getAdditionalPlannedCapacity();  // capacity added by previous strategies _this round_%0A        int currentDemand = snapshot.getQueueLength();%0A        LOGGER.log(Level.FINE, %22Available capacity=%7B0%7D, currentDemand=%7B1%7D%22,%0A                new Object%5B%5D%7BavailableCapacity, currentDemand%7D);%0A        if (availableCapacity %3C currentDemand) %7B%0A%0A            for (Cloud cloud : Jenkins.getInstance().clouds) %7B%0A                if (!cloud.canProvision(label)) continue;%0A%0A                Collection%3CNodeProvisioner.PlannedNode%3E plannedNodes = cloud.provision(label, currentDemand - availableCapacity);%0A                LOGGER.log(Level.FINE, %22Planned %7B0%7D new nodes%22, plannedNodes.size());%0A                strategyState.recordPendingLaunches(plannedNodes);%0A                availableCapacity += plannedNodes.size();%0A                LOGGER.log(Level.FINE, %22After provisioning, available capacity=%7B0%7D, currentDemand=%7B1%7D%22,%0A                        new Object%5B%5D%7BavailableCapacity, currentDemand%7D);%0A                break;%0A            %7D%0A        %7D%0A        if (availableCapacity %3E= currentDemand) %7B%0A            LOGGER.log(Level.FINE, %22Provisioning completed%22);%0A            return NodeProvisioner.StrategyDecision.PROVISIONING_COMPLETED;%0A        %7D else %7B%0A            LOGGER.log(Level.FINE, %22Provisioning not complete, consulting remaining strategies%22);%0A            return NodeProvisioner.StrategyDecision.CONSULT_REMAINING_STRATEGIES;%0A        %7D%0A    %7D%0A%0A%7D

introduce a ProvisionerStrategy to provision a node without delay As AWS now bills by the minute, there's no reason to wait based on load estimates to avoid over-provisioning