package hudson.plugins.ec2;

import hudson.Extension;
import hudson.model.Label;
import hudson.model.LoadStatistics;
import hudson.slaves.Cloud;
import hudson.slaves.NodeProvisioner;
import jenkins.model.Jenkins;

import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 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) {

            for (Cloud cloud : Jenkins.getInstance().clouds) {
                if (!(cloud instanceof AmazonEC2Cloud)) continue;
                if (!cloud.canProvision(label)) continue;
                AmazonEC2Cloud ec2 = (AmazonEC2Cloud) 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;
        }
    }

}
@@ -1764,17 +1764,124 @@
 mand) %7B%0A
-%0A
+            Jenkins jenkinsInstance = Jenkins.getInstance();%0A            if (jenkinsInstance != null) %7B%0A    
         
@@ -1903,35 +1903,31 @@
 cloud : 
-J
+j
 enkins
-.get
 Instance
 ().cloud
@@ -1918,18 +1918,16 @@
 Instance
-()
 .clouds)
@@ -1925,24 +1925,28 @@
 e.clouds) %7B%0A
+    
             
@@ -2011,24 +2011,28 @@
             
+    
 if (!cloud.c
@@ -2077,16 +2077,20 @@
         
+ 
+   
 AmazonEC
@@ -2126,16 +2126,20 @@
  cloud;%0A
+    
         
@@ -2191,16 +2191,20 @@
 tinue;%0A%0A
+    
         
@@ -2333,32 +2333,36 @@
                 
+ 
+   
 LOGGER.log(Level
@@ -2431,16 +2431,20 @@
         
+   
+ 
 strategy
@@ -2502,16 +2502,20 @@
         
+    
 availabl
@@ -2556,32 +2556,36 @@
                 
+ 
+   
 LOGGER.log(Level
@@ -2659,32 +2659,8 @@
 1%7D%22,
-%0A                       
  new
@@ -2725,15 +2725,37 @@
     
+    
 break;%0A
+                %7D%0A
     

Fix findbugs bug