Skip to content

Commit 15f44f3

Browse files
committed
Add HystrixThreadPoolProperties#actualMaximumSize()
This centralizes the logic on how to determine the correct value to actually set the threadpool's max to. It now treats HystrixThreadPoolProperties#maximumSize() as the value configured (but possibly not used)
1 parent 362abc0 commit 15f44f3

File tree

9 files changed

+208
-54
lines changed

9 files changed

+208
-54
lines changed

Diff for: hystrix-contrib/hystrix-codahale-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/codahalemetricspublisher/HystrixCodaHaleMetricsPublisherThreadPool.java

+7
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ public Number getValue() {
153153
}
154154
});
155155

156+
metricRegistry.register(createMetricName("propertyValue_actualMaximumSize"), new Gauge<Number>() {
157+
@Override
158+
public Number getValue() {
159+
return properties.maximumSize().get();
160+
}
161+
});
162+
156163
metricRegistry.register(createMetricName("propertyValue_keepAliveTimeInMinutes"), new Gauge<Number>() {
157164
@Override
158165
public Number getValue() {

Diff for: hystrix-contrib/hystrix-metrics-event-stream/src/main/java/com/netflix/hystrix/contrib/sample/stream/HystrixConfigurationJsonStream.java

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ private static void writeThreadPoolConfigJson(JsonGenerator json, HystrixThreadP
117117
json.writeObjectFieldStart(threadPoolKey.name());
118118
json.writeNumberField("coreSize", threadPoolConfig.getCoreSize());
119119
json.writeNumberField("maximumSize", threadPoolConfig.getMaximumSize());
120+
json.writeNumberField("actualMaximumSize", threadPoolConfig.getActualMaximumSize());
120121
json.writeNumberField("maxQueueSize", threadPoolConfig.getMaxQueueSize());
121122
json.writeNumberField("queueRejectionThreshold", threadPoolConfig.getQueueRejectionThreshold());
122123
json.writeNumberField("keepAliveTimeInMinutes", threadPoolConfig.getKeepAliveTimeInMinutes());

Diff for: hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherThreadPool.java

+7
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,13 @@ public Number getValue() {
256256
}
257257
});
258258

259+
monitors.add(new InformationalMetric<Number>(MonitorConfig.builder("propertyValue_actualMaximumSize").build()) {
260+
@Override
261+
public Number getValue() {
262+
return properties.actualMaximumSize();
263+
}
264+
});
265+
259266
monitors.add(new InformationalMetric<Number>(MonitorConfig.builder("propertyValue_keepAliveTimeInMinutes").build()) {
260267
@Override
261268
public Number getValue() {

Diff for: hystrix-contrib/hystrix-yammer-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/yammermetricspublisher/HystrixYammerMetricsPublisherThreadPool.java

+7
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ public Number value() {
149149
}
150150
});
151151

152+
metricsRegistry.newGauge(createMetricName("propertyValue_actualMaximumSize"), new Gauge<Number>() {
153+
@Override
154+
public Number value() {
155+
return properties.actualMaximumSize();
156+
}
157+
});
158+
152159
metricsRegistry.newGauge(createMetricName("propertyValue_keepAliveTimeInMinutes"), new Gauge<Number>() {
153160
@Override
154161
public Number value() {

Diff for: hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPool.java

+8-13
Original file line numberDiff line numberDiff line change
@@ -209,31 +209,26 @@ public Scheduler getScheduler(Func0<Boolean> shouldInterruptThread) {
209209
// allow us to change things via fast-properties by setting it each time
210210
private void touchConfig() {
211211
final int dynamicCoreSize = properties.coreSize().get();
212-
final int dynamicMaximumSize = properties.maximumSize().get();
213-
int updatedMaximumSize = dynamicMaximumSize;
212+
final int configuredMaximumSize = properties.maximumSize().get();
213+
int dynamicMaximumSize = properties.actualMaximumSize();
214214
final boolean allowSizesToDiverge = properties.getAllowMaximumSizeToDivergeFromCoreSize().get();
215215
boolean maxTooLow = false;
216216

217-
if (allowSizesToDiverge && dynamicMaximumSize < dynamicCoreSize) {
217+
if (allowSizesToDiverge && configuredMaximumSize < dynamicCoreSize) {
218218
//if user sets maximum < core (or defaults get us there), we need to maintain invariant of core <= maximum
219-
updatedMaximumSize = dynamicCoreSize;
219+
dynamicMaximumSize = dynamicCoreSize;
220220
maxTooLow = true;
221221
}
222222

223-
if (!allowSizesToDiverge) {
224-
//if user has not opted in to allowing sizes to diverge, ensure maximum == core
225-
updatedMaximumSize = dynamicCoreSize;
226-
}
227-
228223
// In JDK 6, setCorePoolSize and setMaximumPoolSize will execute a lock operation. Avoid them if the pool size is not changed.
229-
if (threadPool.getCorePoolSize() != dynamicCoreSize || (allowSizesToDiverge && threadPool.getMaximumPoolSize() != updatedMaximumSize)) {
224+
if (threadPool.getCorePoolSize() != dynamicCoreSize || (allowSizesToDiverge && threadPool.getMaximumPoolSize() != dynamicMaximumSize)) {
230225
if (maxTooLow) {
231226
logger.error("Hystrix ThreadPool configuration for : " + metrics.getThreadPoolKey().name() + " is trying to set coreSize = " +
232-
dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ". Maximum size will be set to " +
233-
dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
227+
dynamicCoreSize + " and maximumSize = " + configuredMaximumSize + ". Maximum size will be set to " +
228+
dynamicMaximumSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
234229
}
235230
threadPool.setCorePoolSize(dynamicCoreSize);
236-
threadPool.setMaximumPoolSize(updatedMaximumSize);
231+
threadPool.setMaximumPoolSize(dynamicMaximumSize);
237232
}
238233

239234
threadPool.setKeepAliveTime(properties.keepAliveTimeMinutes().get(), TimeUnit.MINUTES);

Diff for: hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolProperties.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,39 @@ public HystrixProperty<Integer> coreSize() {
116116
}
117117

118118
/**
119-
* Maximum thread-pool size that gets passed to {@link ThreadPoolExecutor#setMaximumPoolSize(int)}
119+
* Maximum thread-pool size configured for threadpool. May conflict with other config, so if you need the
120+
* actual value that gets passed to {@link ThreadPoolExecutor#setMaximumPoolSize(int)}, use {@link #actualMaximumSize()}
120121
*
121122
* @return {@code HystrixProperty<Integer>}
122123
*/
123124
public HystrixProperty<Integer> maximumSize() {
124125
return maximumPoolSize;
125126
}
126127

128+
/**
129+
* Given all of the thread pool configuration, what is the actual maximumSize applied to the thread pool
130+
* via {@link ThreadPoolExecutor#setMaximumPoolSize(int)}
131+
*
132+
* Cases:
133+
* 1) allowMaximumSizeToDivergeFromCoreSize == false: maximumSize is set to coreSize
134+
* 2) allowMaximumSizeToDivergeFromCoreSize == true, maximumSize >= coreSize: thread pool has different core/max sizes, so return the configured max
135+
* 3) allowMaximumSizeToDivergeFromCoreSize == true, maximumSize < coreSize: threadpool incorrectly configured, use coreSize for max size
136+
* @return actually configured maximum size of threadpool
137+
*/
138+
public Integer actualMaximumSize() {
139+
final int coreSize = coreSize().get();
140+
final int maximumSize = maximumSize().get();
141+
if (allowMaximumSizeToDivergeFromCoreSize.get()) {
142+
if (coreSize > maximumSize) {
143+
return coreSize;
144+
} else {
145+
return maximumSize;
146+
}
147+
} else {
148+
return coreSize;
149+
}
150+
}
151+
127152
/**
128153
* Keep-alive time in minutes that gets passed to {@link ThreadPoolExecutor#setKeepAliveTime(long, TimeUnit)}
129154
*

Diff for: hystrix-core/src/main/java/com/netflix/hystrix/config/HystrixThreadPoolConfiguration.java

+31-26
Original file line numberDiff line numberDiff line change
@@ -19,53 +19,45 @@
1919
import com.netflix.hystrix.HystrixThreadPoolProperties;
2020

2121
public class HystrixThreadPoolConfiguration {
22-
//The idea is for this object to be serialized off-box. For future-proofing, I'm adding a version so that changing config over time can be handled gracefully
23-
private static final String VERSION = "1";
2422
private final HystrixThreadPoolKey threadPoolKey;
2523
private final int coreSize;
2624
private final int maximumSize;
25+
private final int actualMaximumSize;
2726
private final int maxQueueSize;
2827
private final int queueRejectionThreshold;
2928
private final int keepAliveTimeInMinutes;
3029
private final boolean allowMaximumSizeToDivergeFromCoreSize;
3130
private final int rollingCounterNumberOfBuckets;
3231
private final int rollingCounterBucketSizeInMilliseconds;
3332

34-
public HystrixThreadPoolConfiguration(HystrixThreadPoolKey threadPoolKey, int coreSize, int maximumSize, int maxQueueSize, int queueRejectionThreshold,
33+
private HystrixThreadPoolConfiguration(HystrixThreadPoolKey threadPoolKey, int coreSize, int maximumSize, int actualMaximumSize, int maxQueueSize, int queueRejectionThreshold,
3534
int keepAliveTimeInMinutes, boolean allowMaximumSizeToDivergeFromCoreSize, int rollingCounterNumberOfBuckets,
3635
int rollingCounterBucketSizeInMilliseconds) {
3736
this.threadPoolKey = threadPoolKey;
3837
this.allowMaximumSizeToDivergeFromCoreSize = allowMaximumSizeToDivergeFromCoreSize;
3938
this.coreSize = coreSize;
40-
if (allowMaximumSizeToDivergeFromCoreSize) {
41-
if (coreSize > maximumSize) {
42-
this.maximumSize = coreSize;
43-
} else {
44-
this.maximumSize = maximumSize;
45-
}
46-
} else {
47-
this.maximumSize = coreSize;
48-
}
39+
this.maximumSize = maximumSize;
40+
this.actualMaximumSize = actualMaximumSize;
4941
this.maxQueueSize = maxQueueSize;
5042
this.queueRejectionThreshold = queueRejectionThreshold;
5143
this.keepAliveTimeInMinutes = keepAliveTimeInMinutes;
5244
this.rollingCounterNumberOfBuckets = rollingCounterNumberOfBuckets;
5345
this.rollingCounterBucketSizeInMilliseconds = rollingCounterBucketSizeInMilliseconds;
5446
}
5547

56-
public static HystrixThreadPoolConfiguration sample(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
57-
return new HystrixThreadPoolConfiguration(
58-
threadPoolKey,
59-
threadPoolProperties.coreSize().get(),
60-
threadPoolProperties.maximumSize().get(),
61-
threadPoolProperties.maxQueueSize().get(),
62-
threadPoolProperties.queueSizeRejectionThreshold().get(),
63-
threadPoolProperties.keepAliveTimeMinutes().get(),
64-
threadPoolProperties.getAllowMaximumSizeToDivergeFromCoreSize().get(),
48+
private HystrixThreadPoolConfiguration(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
49+
this(threadPoolKey, threadPoolProperties.coreSize().get(),
50+
threadPoolProperties.maximumSize().get(), threadPoolProperties.actualMaximumSize(),
51+
threadPoolProperties.maxQueueSize().get(), threadPoolProperties.queueSizeRejectionThreshold().get(),
52+
threadPoolProperties.keepAliveTimeMinutes().get(), threadPoolProperties.getAllowMaximumSizeToDivergeFromCoreSize().get(),
6553
threadPoolProperties.metricsRollingStatisticalWindowBuckets().get(),
6654
threadPoolProperties.metricsRollingStatisticalWindowInMilliseconds().get());
6755
}
6856

57+
public static HystrixThreadPoolConfiguration sample(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
58+
return new HystrixThreadPoolConfiguration(threadPoolKey, threadPoolProperties);
59+
}
60+
6961
public HystrixThreadPoolKey getThreadPoolKey() {
7062
return threadPoolKey;
7163
}
@@ -74,12 +66,25 @@ public int getCoreSize() {
7466
return coreSize;
7567
}
7668

69+
/**
70+
* Simple getter that returns what the `maximumSize` property is configured as
71+
* @return
72+
*/
7773
public int getMaximumSize() {
78-
if (allowMaximumSizeToDivergeFromCoreSize) {
79-
return maximumSize;
80-
} else {
81-
return coreSize;
82-
}
74+
return maximumSize;
75+
}
76+
77+
/**
78+
* Given all of the thread pool configuration, what is the actual maximumSize applied to the thread pool.
79+
*
80+
* Cases:
81+
* 1) allowMaximumSizeToDivergeFromCoreSize == false: maximumSize is set to coreSize
82+
* 2) allowMaximumSizeToDivergeFromCoreSize == true, maximumSize >= coreSize: thread pool has different core/max sizes, so return the configured max
83+
* 3) allowMaximumSizeToDivergeFromCoreSize == true, maximumSize < coreSize: threadpool incorrectly configured, use coreSize for max size
84+
* @return actually configured maximum size of threadpool
85+
*/
86+
public int getActualMaximumSize() {
87+
return this.actualMaximumSize;
8388
}
8489

8590
public int getMaxQueueSize() {

0 commit comments

Comments
 (0)