From f69f55c8861d531516315ef8caa62e457cea0df1 Mon Sep 17 00:00:00 2001 From: Kolton Andrus Date: Fri, 19 Sep 2014 15:58:08 -0700 Subject: [PATCH] Add support for execution.isolation.semaphore.timeoutInMilliseconds --- .../hystrix/HystrixCommandProperties.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandProperties.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandProperties.java index a8e08a80c..37cb47e4d 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandProperties.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandProperties.java @@ -46,6 +46,7 @@ public abstract class HystrixCommandProperties { private static final Boolean default_circuitBreakerForceOpen = false;// default => forceCircuitOpen = false (we want to allow traffic) /* package */ static final Boolean default_circuitBreakerForceClosed = false;// default => ignoreErrors = false private static final Integer default_executionIsolationThreadTimeoutInMilliseconds = 1000; // default => executionTimeoutInMilliseconds: 1000 = 1 second + private static final Integer default_executionIsolationSemaphoreTimeoutInMilliseconds = 1000; // default => executionTimeoutInMilliseconds: 1000 = 1 second private static final ExecutionIsolationStrategy default_executionIsolationStrategy = ExecutionIsolationStrategy.THREAD; private static final Boolean default_executionIsolationThreadInterruptOnTimeout = true; private static final Boolean default_metricsRollingPercentileEnabled = true; @@ -60,7 +61,7 @@ public abstract class HystrixCommandProperties { private static final Integer default_metricsRollingPercentileBucketSize = 100; // default to 100 values max per bucket private static final Integer default_metricsHealthSnapshotIntervalInMilliseconds = 500; // default to 500ms as max frequency between allowing snapshots of health (error percentage etc) - private final HystrixCommandKey key; + @SuppressWarnings("unused") private final HystrixCommandKey key; private final HystrixProperty circuitBreakerRequestVolumeThreshold; // number of requests that must be made within a statisticalWindow before open/close decisions are made using stats private final HystrixProperty circuitBreakerSleepWindowInMilliseconds; // milliseconds after tripping circuit before allowing retry private final HystrixProperty circuitBreakerEnabled; // Whether circuit breaker should be enabled. @@ -70,6 +71,7 @@ public abstract class HystrixCommandProperties { private final HystrixProperty executionIsolationStrategy; // Whether a command should be executed in a separate thread or not. private final HystrixProperty executionIsolationThreadTimeoutInMilliseconds; // Timeout value in milliseconds for a command being executed in a thread. private final HystrixProperty executionIsolationThreadPoolKeyOverride; // What thread-pool this command should run in (if running on a separate thread). + private final HystrixProperty executionIsolationSemaphoreTimeoutInMilliseconds; // Timeout value in milliseconds for a async semaphore command being executed. private final HystrixProperty executionIsolationSemaphoreMaxConcurrentRequests; // Number of permits for execution semaphore private final HystrixProperty fallbackIsolationSemaphoreMaxConcurrentRequests; // Number of permits for fallback semaphore private final HystrixProperty fallbackEnabled; // Whether fallback should be attempted. @@ -116,6 +118,7 @@ protected HystrixCommandProperties(HystrixCommandKey key, HystrixCommandProperti this.executionIsolationStrategy = getProperty(propertyPrefix, key, "execution.isolation.strategy", builder.getExecutionIsolationStrategy(), default_executionIsolationStrategy); this.executionIsolationThreadTimeoutInMilliseconds = getProperty(propertyPrefix, key, "execution.isolation.thread.timeoutInMilliseconds", builder.getExecutionIsolationThreadTimeoutInMilliseconds(), default_executionIsolationThreadTimeoutInMilliseconds); this.executionIsolationThreadInterruptOnTimeout = getProperty(propertyPrefix, key, "execution.isolation.thread.interruptOnTimeout", builder.getExecutionIsolationThreadInterruptOnTimeout(), default_executionIsolationThreadInterruptOnTimeout); + this.executionIsolationSemaphoreTimeoutInMilliseconds = getProperty(propertyPrefix, key, "execution.isolation.semaphore.timeoutInMilliseconds", builder.getExecutionIsolationSemaphoreTimeoutInMilliseconds(), default_executionIsolationSemaphoreTimeoutInMilliseconds); this.executionIsolationSemaphoreMaxConcurrentRequests = getProperty(propertyPrefix, key, "execution.isolation.semaphore.maxConcurrentRequests", builder.getExecutionIsolationSemaphoreMaxConcurrentRequests(), default_executionIsolationSemaphoreMaxConcurrentRequests); this.fallbackIsolationSemaphoreMaxConcurrentRequests = getProperty(propertyPrefix, key, "fallback.isolation.semaphore.maxConcurrentRequests", builder.getFallbackIsolationSemaphoreMaxConcurrentRequests(), default_fallbackIsolationSemaphoreMaxConcurrentRequests); this.fallbackEnabled = getProperty(propertyPrefix, key, "fallback.enabled", builder.getFallbackEnabled(), default_fallbackEnabled); @@ -260,6 +263,19 @@ public HystrixProperty executionIsolationThreadPoolKeyOverride() { public HystrixProperty executionIsolationThreadTimeoutInMilliseconds() { return executionIsolationThreadTimeoutInMilliseconds; } + + /** + * Time in milliseconds at which point the async command will be cancelled. + *

+ * If {@link #executionIsolationSemaphoreInterruptOnTimeout} == true the executing command will be cancelled. + *

+ * Applicable only when {@link #executionIsolationStrategy()} == SEMAPHORE. + * + * @return {@code HystrixProperty} + */ + public HystrixProperty executionIsolationSemaphoreTimeoutInMilliseconds() { + return executionIsolationSemaphoreTimeoutInMilliseconds; + } /** * Number of concurrent requests permitted to {@link HystrixCommand#getFallback()}. Requests beyond the concurrent limit will fail-fast and not attempt retrieving a fallback. @@ -393,7 +409,6 @@ private static HystrixProperty getProperty(String propertyPrefix, Hystri new HystrixPropertiesChainedArchaiusProperty.DynamicStringProperty(propertyPrefix + ".command.default." + instanceProperty, defaultValue))); } - @SuppressWarnings("unused") private static HystrixProperty getProperty(final String propertyPrefix, final HystrixCommandKey key, final String instanceProperty, final ExecutionIsolationStrategy builderOverrideValue, final ExecutionIsolationStrategy defaultValue) { return new ExecutionIsolationStrategyHystrixProperty(builderOverrideValue, key, propertyPrefix, defaultValue, instanceProperty); @@ -482,6 +497,7 @@ public static class Setter { private ExecutionIsolationStrategy executionIsolationStrategy = null; private Boolean executionIsolationThreadInterruptOnTimeout = null; private Integer executionIsolationThreadTimeoutInMilliseconds = null; + private Integer executionIsolationSemaphoreTimeoutInMilliseconds = null; private Integer fallbackIsolationSemaphoreMaxConcurrentRequests = null; private Boolean fallbackEnabled = null; private Integer metricsHealthSnapshotIntervalInMilliseconds = null; @@ -537,6 +553,10 @@ public Boolean getExecutionIsolationThreadInterruptOnTimeout() { public Integer getExecutionIsolationThreadTimeoutInMilliseconds() { return executionIsolationThreadTimeoutInMilliseconds; } + + public Integer getExecutionIsolationSemaphoreTimeoutInMilliseconds() { + return executionIsolationSemaphoreTimeoutInMilliseconds; + } public Integer getFallbackIsolationSemaphoreMaxConcurrentRequests() { return fallbackIsolationSemaphoreMaxConcurrentRequests; @@ -632,6 +652,19 @@ public Setter withExecutionIsolationThreadTimeoutInMilliseconds(int value) { return this; } + public Setter withExecutionIsolationSemaphoreTimeoutInMilliseconds(int value) { + this.executionIsolationSemaphoreTimeoutInMilliseconds = value; + return this; + } + + + public Setter withTimeoutInMilliseconds(int value) { + // We can set both values here, as only one will be applicable (based upon executionIsolation) + this.executionIsolationThreadTimeoutInMilliseconds = value; + this.executionIsolationSemaphoreTimeoutInMilliseconds = value; + return this; + } + public Setter withFallbackIsolationSemaphoreMaxConcurrentRequests(int value) { this.fallbackIsolationSemaphoreMaxConcurrentRequests = value; return this;