@@ -30,63 +30,64 @@ public NodeProvisioner.StrategyDecision apply(final NodeProvisioner.StrategyStat
30
30
final Label label = strategyState .getLabel ();
31
31
32
32
final LoadStatistics .LoadStatisticsSnapshot snapshot = strategyState .getSnapshot ();
33
- final int availableCapacity =
34
- snapshot .getAvailableExecutors () // live executors
35
- + snapshot .getConnectingExecutors () // executors present but not yet connected
36
- + strategyState .getPlannedCapacitySnapshot () // capacity added by previous strategies from previous rounds
37
- + strategyState .getAdditionalPlannedCapacity (); // capacity added by previous strategies _this round_
38
-
39
- int currentDemand = snapshot .getQueueLength () - availableCapacity ;
40
- LOGGER .log (currentDemand < 1 ? Level .FINE : Level .INFO ,
41
- "label [{0}]: currentDemand {1} availableCapacity {2} (availableExecutors {3} connectingExecutors {4} plannedCapacitySnapshot {5} additionalPlannedCapacity {6})" ,
42
- new Object []{label , currentDemand , availableCapacity , snapshot .getAvailableExecutors (),
43
- snapshot .getConnectingExecutors (), strategyState .getPlannedCapacitySnapshot (),
44
- strategyState .getAdditionalPlannedCapacity ()});
45
-
46
- for (final Cloud cloud : getClouds ()) {
47
- if (currentDemand < 1 ) {
48
- LOGGER .log (Level .FINE , "label [{0}]: currentDemand is less than 1, not provisioning" , label );
33
+ final int availableCapacity = snapshot .getAvailableExecutors () // available executors
34
+ + strategyState .getPlannedCapacitySnapshot () // capacity added by previous strategies from previous rounds
35
+ + strategyState .getAdditionalPlannedCapacity (); // capacity added by previous strategies _this round_
36
+
37
+ int qLen = snapshot .getQueueLength ();
38
+ int excessWorkload = qLen - availableCapacity ;
39
+ LOGGER .log (Level .FINE , "label [{0}]: queueLength {1} availableCapacity {2} (availableExecutors {3} plannedCapacitySnapshot {4} additionalPlannedCapacity {5})" ,
40
+ new Object []{label , qLen , availableCapacity , snapshot .getAvailableExecutors (),
41
+ strategyState .getPlannedCapacitySnapshot (), strategyState .getAdditionalPlannedCapacity ()});
42
+
43
+ if (excessWorkload <= 0 ) {
44
+ LOGGER .log (Level .INFO , "label [{0}]: No excess workload, provisioning not needed." , label );
45
+ return NodeProvisioner .StrategyDecision .PROVISIONING_COMPLETED ;
46
+ }
47
+
48
+ for (final Cloud c : getClouds ()) {
49
+ if (excessWorkload < 1 ) {
49
50
break ;
50
51
}
51
52
52
- if (!(cloud instanceof EC2FleetCloud )) {
53
+ if (!(c instanceof EC2FleetCloud )) {
53
54
LOGGER .log (Level .FINE , "label [{0}]: cloud {1} is not an EC2FleetCloud, continuing..." ,
54
- new Object []{label , cloud .getDisplayName ()});
55
+ new Object []{label , c .getDisplayName ()});
55
56
continue ;
56
57
}
57
58
58
59
Cloud .CloudState cloudState = new Cloud .CloudState (label , strategyState .getAdditionalPlannedCapacity ());
59
- if (!cloud .canProvision (cloudState )) {
60
+ if (!c .canProvision (cloudState )) {
60
61
LOGGER .log (Level .INFO , "label [{0}]: cloud {1} can not provision for this label, continuing..." ,
61
- new Object []{label , cloud .getDisplayName ()});
62
+ new Object []{label , c .getDisplayName ()});
62
63
continue ;
63
64
}
64
65
65
- final EC2FleetCloud ec2 = (EC2FleetCloud ) cloud ;
66
- if (!ec2 .isNoDelayProvision ()) {
66
+ if (!((EC2FleetCloud ) c ).isNoDelayProvision ()) {
67
67
LOGGER .log (Level .FINE , "label [{0}]: cloud {1} does not use No Delay Provision Strategy, continuing..." ,
68
- new Object []{label , cloud .getDisplayName ()});
68
+ new Object []{label , c .getDisplayName ()});
69
69
continue ;
70
70
}
71
71
72
- LOGGER .log (Level .INFO , "label [{0}]: cloud {1} can provision for this label" ,
73
- new Object []{label , cloud .getDisplayName ()});
74
- final Collection <NodeProvisioner .PlannedNode > plannedNodes = cloud .provision (cloudState , currentDemand );
75
- for (NodeProvisioner .PlannedNode plannedNode : plannedNodes ) {
76
- currentDemand -= plannedNode .numExecutors ;
72
+ LOGGER .log (Level .FINE , "label [{0}]: cloud {1} can provision for this label" ,
73
+ new Object []{label , c .getDisplayName ()});
74
+ final Collection <NodeProvisioner .PlannedNode > plannedNodes = c .provision (cloudState , excessWorkload );
75
+ for (NodeProvisioner .PlannedNode pn : plannedNodes ) {
76
+ excessWorkload -= pn .numExecutors ;
77
+ LOGGER .log (Level .INFO , "Started provisioning {0} from {1} with {2,number,integer} "
78
+ + "executors. Remaining excess workload: {3,number,#.###}" ,
79
+ new Object []{pn .displayName , c .name , pn .numExecutors , excessWorkload });
77
80
}
78
- LOGGER .log (Level .FINE , "Planned {0} new nodes" , plannedNodes .size ());
79
81
strategyState .recordPendingLaunches (plannedNodes );
80
- LOGGER .log (Level .FINE , "After provisioning currentDemand={0}" , new Object []{currentDemand });
81
82
}
82
83
83
- if (currentDemand < 1 ) {
84
- LOGGER .log (Level .FINE , "Provisioning completed" );
85
- return NodeProvisioner .StrategyDecision .PROVISIONING_COMPLETED ;
86
- } else {
84
+ if (excessWorkload > 0 ) {
87
85
LOGGER .log (Level .FINE , "Provisioning not complete, consulting remaining strategies" );
88
86
return NodeProvisioner .StrategyDecision .CONSULT_REMAINING_STRATEGIES ;
89
87
}
88
+
89
+ LOGGER .log (Level .FINE , "Provisioning completed" );
90
+ return NodeProvisioner .StrategyDecision .PROVISIONING_COMPLETED ;
90
91
}
91
92
92
93
// Visible for testing
0 commit comments