7676import java .util .concurrent .ConcurrentMap ;
7777import java .util .concurrent .CopyOnWriteArrayList ;
7878import java .util .concurrent .ExecutionException ;
79+ import java .util .concurrent .atomic .AtomicInteger ;
7980import java .util .logging .Level ;
8081import java .util .logging .Logger ;
8182import java .util .regex .Pattern ;
@@ -142,7 +143,7 @@ public class JCloudsCloud extends Cloud {
142143 @ Deprecated
143144 private final transient String publicKey ; // NOPMD - unused private member
144145
145- private transient int pendingNodes ;
146+ private transient AtomicInteger pendingNodes ;
146147
147148 public final String endPointUrl ;
148149 public final String profile ;
@@ -446,6 +447,12 @@ void fillLocationIdItems(ListBoxModel m) {
446447 }
447448 }
448449
450+ private synchronized void initPendingNodes () {
451+ if (null == pendingNodes ) {
452+ pendingNodes = new AtomicInteger (0 );
453+ }
454+ }
455+
449456 @ DataBoundConstructor
450457 public JCloudsCloud (
451458 final String profile ,
@@ -482,7 +489,7 @@ public JCloudsCloud(
482489 this .trustAll = trustAll ;
483490 this .groupPrefix = groupPrefix ;
484491 readResolve ();
485- this . pendingNodes = 0 ;
492+ initPendingNodes () ;
486493 }
487494
488495 protected Object readResolve () {
@@ -651,7 +658,8 @@ public Collection<NodeProvisioner.PlannedNode> provision(Cloud.CloudState state,
651658 && !Jenkins .get ().isQuietingDown ()
652659 && !Jenkins .get ().isTerminating ()) {
653660
654- if ((getRunningNodesCount () + plannedNodeList .size () + pendingNodes ) >= instanceCap ) {
661+ initPendingNodes ();
662+ if ((getRunningNodesCount () + plannedNodeList .size () + pendingNodes .intValue ()) >= instanceCap ) {
655663 LOGGER .info (String .format (
656664 "Instance cap of %s reached while adding capacity for label %s" ,
657665 getName (), (label != null ) ? label .toString () : "null" ));
@@ -665,11 +673,11 @@ public Collection<NodeProvisioner.PlannedNode> provision(Cloud.CloudState state,
665673 public Node call () throws Exception {
666674 // TODO: record the output somewhere
667675 JCloudsSlave jcloudsSlave ;
668- pendingNodes ++ ;
676+ pendingNodes . incrementAndGet () ;
669677 try {
670678 jcloudsSlave = tpl .provisionSlave (StreamTaskListener .fromStdout (), provisioningId );
671679 } finally {
672- pendingNodes -- ;
680+ pendingNodes . decrementAndGet () ;
673681 }
674682 Jenkins .get ().addNode (jcloudsSlave );
675683
@@ -875,13 +883,14 @@ public void doProvision(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParamet
875883 return ;
876884 }
877885
878- if (getRunningNodesCount () + pendingNodes < instanceCap ) {
886+ initPendingNodes ();
887+ if (getRunningNodesCount () + pendingNodes .intValue () < instanceCap ) {
879888 try {
880- pendingNodes ++ ;
889+ pendingNodes . incrementAndGet () ;
881890 JCloudsSlave node = doProvisionFromTemplate (t );
882891 rsp .sendRedirect2 (req .getContextPath () + "/computer/" + node .getNodeName ());
883892 } finally {
884- pendingNodes -- ;
893+ pendingNodes . decrementAndGet () ;
885894 }
886895 } else {
887896 sendError (String .format ("Instance cap of %s reached" , getName ()), req , rsp );
0 commit comments