When using the Circuit Breaker Pattern, is it ok to wrap all the external services calls in a method that is passed to the .withCircuitBreaker()
or each call in itself should be passed to the .withCircuitBreaker()
?
eg.
// wrapped
def wrapper(param: T) : Future[Option[T]] = {
externalCall1(param)
externalCall2(param)
}
circuitBreaker.withCircuitBreaker(wrapper(someParam))
// one-by-one
circuitBreaker.withCircuitBreaker(externalCall1(param))
circuitBreaker.withCircuitBreaker(externalCall2(param))
Update: In case of a web service is it ok to register the circuit breaker in the mainActorSystem
or I should use a separate circuitBreakerActorSystem
?
It depends. Can the caller survive when just one of the services fails? I mean, imagine that only externalCall2
fails, will your service be able to keep going or it needs that both calls works?
If you highly depends on both calls, wrap both sounds like a good idea. There is no point in call externalCall1
if externalCall2
fails and you need both. The suggestion here is to have some kind of fallback/backup when the circuit is open.
If otherwise the calls are independent of each other, then you should probably have separated circuit breakers for each one of then. Again, you can have some kind of backup/fallback when the circuit is open.
A possible fallback/backup is to use a cache and return the cached value when the circuit is open. ScalaCache is a good option here. It can work with a in process cache like Ehcache or with Redis and have async/sync APIs.