Jaro
03/24/2023, 3:54 PMCompletableFuture code in Java to Coroutines in Kotlin, the interface that my Kotlin class implements has functions that are returning CompletableFuture
Here is example of functions that I want to rewrite
private final Map<String, FooWrapper> fooRequests = new ConcurrentHashMap<>();
public CompletableFuture<FooResponse> retrieveFoo(FooRequest request) {
return completedFuture(...)
.thenAccept(client::callFoo)
.thenCompose(ignore -> storeFooRequest(request))
.whenComplete((response, error) -> log(request, error));
}
private CompletableFuture<FooResponse> storeFooRequest(FooRequest request) {
var fooWrapper = new FooWrapper(request, new CompletableFuture<>());
fooRequests.put(request.getId(), fooWrapper);
return fooWrapper.getResponseFuture();
}
eventually there will be call to other functions that will call complete on a CompletableFuture stored in fooRequests and allowing completion of retrieveFoo
here is my Kotlin code
private val fooRequests: ConcurrentHashMap<String, CompletableDeferred<FooResponse>> = ConcurrentHashMap()
override fun retrieveFoo(request: FooRequest): CompletableFuture<FooResponse> {
return GlobalScope.future {
retrieveQuoteAsync(request)
}
}
private suspend fun retrieveFooAsync(request: FooRequest): Deferred<FooResponse> {
return coroutineScope {
storeFooRequest(request)//.await()
}
}
private suspend fun storeFooRequest(request: FooRequest): Deferred<FooResponse> {
val deferred: CompletableDeferred<FooResponse> = CompletableDeferred()
fooRequests[request.id] = deferred
return deferred
}
I'm trying to replace CompletableFuture with CompletableDeferred but I do not know how to get the value without calling await() , I do not want it to block
Any suggestion how to make it work in similar way to Java?Joffrey
03/24/2023, 3:57 PMCompletableFuture? If that's not the case, you should prefer turning your functions into suspend functions instead, and get rid of the futures in return types, it would simplify everything.Jaro
03/24/2023, 4:00 PMJoffrey
03/24/2023, 4:00 PMbut I do not know how to get the value without calling await() , I do not want it to blockCalling
await() doesn't block. It suspends the current coroutine, which is non-blocking (that's the whole point)Jaro
03/24/2023, 4:01 PMawait() ?Joffrey
03/24/2023, 4:02 PMfuture { ... } coroutine builder already, you can simply await. It will suspend the coroutine created by the future builder without blocking any thread.Joffrey
03/24/2023, 4:05 PMGlobalScope. Use either an existing scope, or create a new scope that is tied to the lifecycle of the component that holds all concurrent coroutines. It probably has a close() or shutdown() method to stop all concurrent work, and you should use it to cancel all pending requests by cancelling the coroutine scope in which you launched all the coroutinesJaro
03/24/2023, 4:12 PMcancel() on the coroutineScope?Joffrey
03/24/2023, 4:21 PMretrieveFoo as cancelled (isCancelled == true), and calling .get() on them will throw JobCancellationException.Jaro
03/24/2023, 4:31 PM