Hello, I'm using resilience4j and I'm trying to fi...
# coroutines
o
Hello, I'm using resilience4j and I'm trying to figure out a pattern: I want to a function call in a circuit breaker, but this function suspends, so the compiler won't let me do it.
Copy code
decorateCheckedSupplier(circuitBreaker) {
  suspendingFunction() // compiler complains
}
How would I handle this? I've realized that I can wrap the
suspendingFunction
call in an
async
block, but then the circuitbreaker returns a
Deferred
and always succeeds, which is not what I want. What I want, I think, is to have be able to call a suspending function from an arbitrary lambda.
s
Do you need the result of the suspendingFunction ? If not, wrap it in a launch: `launch { suspendingFunction() }’. If you need to wait for the result, wrap it in a
runBlocking
instead.
o
Yeah, I need the result -- so
runBlocking
is the choice here?
s
Yep.
runBlocking
should be used to bridge non-suspend code that can block/wait with suspend code.
g
Does this API provide any async API? If so just write coroutine adapter, so it will convert callback API to suspend function, so you can use it from coroutine
m
This is possible using resilience4js adapters for reactor and the corotines reactor integration. We do it in production and it works really well. I can provide an example in a few minutes
Copy code
suspend fun doSomethingSuspending(){}

fun CoroutineScope.test(){
    //using mono coroutine builder from coroutines reactor
    mono{ doSomethingSuspending() }
        .withCircuitBreaker(circuitBreaker)
        .awaitFirst()
}

fun <T> Mono<T>.withCircuitBreaker(circuitBreaker: CircuitBreaker): Mono<T> =
    this.transform(CircuitBreakerOperator.of(circuitBreaker))
with these deps
Copy code
"io.github.resilience4j:resilience4j-circuitbreaker"
"io.github.resilience4j:resilience4j-reactor"
"org.jetbrains.kotlinx:kotlinx-coroutines-reactor"