Last active
April 12, 2018 13:59
-
-
Save eungju/fcee780c4dc6135bdccfe49f7a7d1c72 to your computer and use it in GitHub Desktop.
Timeout CircuitBreaker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface CircuitBreakerMetrics { | |
fun executionCompleted(name: String, latency: Double) = Unit | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.prometheus.client.Collector | |
import io.prometheus.client.Histogram | |
class PrometheusCircuitBreakerMetrics : CircuitBreakerMetrics, Collector() { | |
override fun collect(): MutableList<MetricFamilySamples> = callLatencyHistogram.collect() | |
private val callLatencyHistogram = Histogram.build() | |
.namespace("resilence4j") | |
.subsystem("circuitbreaker") | |
.name("call_latency_seconds") | |
.labelNames("name") | |
.help("call latency in seconds") | |
.create() | |
override fun executionCompleted(name: String, latency: Double) { | |
callLatencyHistogram.labels(name).observe(latency) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.github.resilience4j.circuitbreaker.CircuitBreaker | |
import java.time.Duration | |
import java.util.concurrent.TimeoutException | |
class TimeoutCircuitBreaker( | |
private val circuitBreaker: CircuitBreaker, | |
private val timeout: Duration, | |
private val metrics: CircuitBreakerMetrics | |
) : CircuitBreaker by circuitBreaker { | |
private val NANOS_PER_SECOND = Duration.ofSeconds(1).toNanos().toDouble() | |
private val timeoutInNanos = timeout.toNanos() | |
override fun onError(durationInNanos: Long, throwable: Throwable) { | |
metrics.executionCompleted(name, durationInNanos / NANOS_PER_SECOND) | |
circuitBreaker.onError(durationInNanos, throwable) | |
} | |
override fun onSuccess(durationInNanos: Long) { | |
if (durationInNanos > timeoutInNanos) { | |
onError(durationInNanos, TimeoutException("An execution of $name takes ${durationInNanos}ns")) | |
} else { | |
metrics.executionCompleted(name, durationInNanos / NANOS_PER_SECOND) | |
circuitBreaker.onSuccess(durationInNanos) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.github.resilience4j.circuitbreaker.CircuitBreaker | |
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig | |
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry | |
import java.time.Duration | |
import java.util.function.Supplier | |
class TimeoutCircuitBreakerRegistry( | |
private val circuitBreakerRegistry: CircuitBreakerRegistry, | |
private val defaultTimeout: Duration, | |
private val metrics: CircuitBreakerMetrics | |
) : CircuitBreakerRegistry by circuitBreakerRegistry { | |
fun decorate(circuitBreaker: CircuitBreaker, timeout: Duration) = | |
TimeoutCircuitBreaker(circuitBreaker, timeout, metrics) | |
fun circuitBreaker(name: String, timeout: Duration): CircuitBreaker = | |
decorate(circuitBreakerRegistry.circuitBreaker(name), timeout) | |
fun circuitBreaker(name: String, circuitBreakerConfig: CircuitBreakerConfig, timeout: Duration): CircuitBreaker = | |
decorate(circuitBreakerRegistry.circuitBreaker(name, circuitBreakerConfig), timeout) | |
fun circuitBreaker( | |
name: String, | |
circuitBreakerConfigSupplier: Supplier<CircuitBreakerConfig>, | |
timeout: Duration | |
): CircuitBreaker = | |
decorate(circuitBreakerRegistry.circuitBreaker(name, circuitBreakerConfigSupplier), timeout) | |
override fun circuitBreaker(name: String): CircuitBreaker = | |
circuitBreaker(name, defaultTimeout) | |
override fun circuitBreaker(name: String, circuitBreakerConfig: CircuitBreakerConfig): CircuitBreaker = | |
circuitBreaker(name, circuitBreakerConfig, defaultTimeout) | |
override fun circuitBreaker( | |
name: String, | |
circuitBreakerConfigSupplier: Supplier<CircuitBreakerConfig> | |
): CircuitBreaker = | |
circuitBreaker(name, circuitBreakerConfigSupplier, defaultTimeout) | |
companion object { | |
@JvmStatic | |
fun ofDefaults() = TimeoutCircuitBreakerRegistry( | |
CircuitBreakerRegistry.ofDefaults(), | |
Duration.ofSeconds(1), object : CircuitBreakerMetrics {}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment