Reputation: 11
I have a reactor chain configured which I would like to retry on failure - I can do this however I am not able to change the context so that the chain knows when it is in a retry.
In the below example I would like for the FLAG value to be "altered" (in deferContextual) during a retry.
const val FLAG = "Flag"
fun main() {
val tr = TestRetry()
tr.main()
}
class TestRetry {
fun main() {
Mono.deferContextual { ctx ->
val flag = ctx.get<Any>(FLAG)
println("flag ${flag}")
Mono.just("hello")
}
.subscribeOn(Schedulers.boundedElastic())
.map {
println("map: $it")
if (true) {
throw IllegalArgumentException()
}
"there"
}
.retryWhen(retrySpec())
.contextWrite {
println("CONTEXT WRITE initialising FLAG")
it.put(FLAG, "original")
}
.subscribe()
Thread.sleep(15000);
}
fun retrySpec(): RetrySpec =
Retry.max(2L)
.doBeforeRetry {
val ctx = it.retryContextView()
val flag = ctx.getOrDefault(FLAG, "oops") // NOTE: here FLAG is altered
println ("DO BEFORE RETRY Flag ${flag}")
}
.filter { throwable ->
throwable is IllegalArgumentException
}
.onRetryExhaustedThrow { _, retrySignal ->
println("retries exhausted")
throw RuntimeException("done")
}.withRetryContext(
Context.of(FLAG, "altered")
)
}
When running the above example I am trying to change the value of the FLAG variable in the withRetryContext
, and I can see that in doBeforeRetry
the value has changed, however when we get back to Mono.deferContextual
the value is back to "original". I don't think I correctly understand how the reactor code works.
Upvotes: 1
Views: 437
Reputation: 8443
There is some sample code of how the context can be modified in the javadoc of retryWhen:
Retry customStrategy = Retry.from(companion -> companion.handle((retrySignal, sink) -> {
Context ctx = sink.currentContext();
int rl = ctx.getOrDefault("retriesLeft", 0);
if (rl > 0) {
sink.next(Context.of(
"retriesLeft", rl - 1,
"lastError", retrySignal.failure()
));
} else {
sink.error(Exceptions.retryExhausted("retries exhausted", retrySignal.failure()));
}
}));
Mono<T> retried = originalMono.retryWhen(customStrategy);
Upvotes: 0