Dasyel Willems
09/29/2020, 3:19 PMIO
to the new suspend
way
We're calling a third-party method which returns a CompletableFuture<Void>
and before we handled it in the following way
async {
run {
doSomethingAsync() //this returns the CompletableFuture<Void>
}
}
How do I correctly go from that completableFuture to a suspend function which returns an Either<MyError, Unit>
Dasyel Willems
09/29/2020, 3:22 PMEither.catch {
doSomethingAsync().await()
}.mapLeft { MyError() }.unit()
this is as far as I got, but I'm not sure if await()
is the correct way to gosimon.vergauwen
09/30/2020, 7:13 AMCompletableFuture
into suspend
you want the following implementation. Which is optimised to return immediately in case the CompletableFuture
is already finished, and adds support for cancellation.
suspend fun <A> CompletableFuture<A>.await(): A =
if (isDone) {
try {
get()
} catch (e: ExecutionException) {
throw e.cause ?: e // unwrap original cause from ExecutionException
}
} else cancellable { callback ->
whenComplete { res, exception ->
if (exception == null) callback(Result.success(res))
else callback(Result.failure((exception as? CompletionException)?.cause ?: exception))
}
CancelToken { cancel(false) }
}
And then you can safely use the snippet you shared in the second snippet. You could also update the above implementation to take a (exception: Throwable) -> E
lambda and return Either<E, A>
immediately.
This method is not available yet in Arrow Fx Coroutines, but would be a welcomed contribution 🙂Kristian
10/02/2020, 5:02 PM