According to the this resilience4j-howto, I'm working on implementing a retry mechanism for asynchronous operations in my Vert.x application using the resilience4j library. I have the following code:
object VertxRetry {
fun <T> executeFuture(
retry: Retry,
vertx: Vertx,
supplier: Supplier<Future<T>>,
retryAccompanyFunction: (() -> Unit)? = null,
): Future<T> {
val ctx = ContextInternal.current()
val promise = if (ctx != null) ctx.promise() else Promise.promise<T>()
AsyncRetryBlock(vertx, retry.asyncContext(), supplier, promise, retryAccompanyFunction).run()
return promise.future()
}
private class AsyncRetryBlock<T>(
private val vertx: Vertx,
private val retryContext: Retry.AsyncContext<T>,
private val supplier: Supplier<Future<T>>,
private val promise: Promise<T>,
private val retryAccompanyFunction: (() -> Unit)? = null,
) : Runnable, Handler<Long?> {
override fun run() {
// Code for run
}
override fun handle(ignored: Long?) {
run()
}
private fun onError(t: Exception) {
// Code for onError
}
private fun onResult(result: T) {
// Code for onResult
}
}
}
The main concern I have is regarding the propagation of the context (e.g., logging context, request context) to the asynchronous operations executed within the AsyncRetryBlock class.
I've tried using ContextInternal.current() to propagate the context, but I'm not entirely sure if this is the correct approach or if there's a better way to achieve this.
My questions are:
Is using ContextInternal the recommended way to propagate the context to the AsyncRetryBlock in this scenario? Or is it necessarily a requirement that we should propagate the context?
Are there any potential issues or pitfalls I should be aware of when using ContextInternal for context propagation?
If this approach is not recommended, what would be the proper way to ensure that the context is propagated correctly to the asynchronous operations?
Any guidance or advice from the community would be greatly appreciated.
The main concern is that I'm not sure if the function in the retry block needs to see the outer context. If not, does below code also work?
val promise = Promise.promise<T>()
AsyncRetryBlock(vertx, retry.asyncContext(), supplier, promise, retryAccompanyFunction).run()