xii
01/27/2022, 11:04 AMasync {
client.get().uri("/userdetail1/${user.login}")
.accept(APPLICATION_JSON)
.awaitExchange().awaitBody<UserDetail1>()
}
am I wrong to think you could just do
val asyncDetail1 = client.get().uri("/userdetail1/${user.login}")
.accept(APPLICATION_JSON)
val asyncDetail2 = client.get().uri("/userdetail2/${user.login}")
.accept(APPLICATION_JSON)
UserWithDetails(user, asyncDetail1.awaitExchange().awaitBody<UserDetail1>(), asyncDetail2.awaitExchange().awaitBody<UserDetail2>())
with the exact same result?Joffrey
01/27/2022, 11:07 AMasync { .. }
makes the block of code asynchronous. This means that the next piece of code will run concurrently with this async
block.
In short, using 2 async
and then awaiting both allows to make those 2 calls concurrently (and possibly in parallel on the right dispatcher)xii
01/27/2022, 11:11 AMJoffrey
01/27/2022, 11:12 AMawaitX
parts in the 2 callsMono
at some point and migrate to coroutines, so there client.get()
could instead be turned into suspending functions. It's kinda one step further towards the migration.xii
01/27/2022, 11:14 AMJoffrey
01/27/2022, 11:14 AMMono
and the rest of the reactive framework works, but there may also be a difference in how both handle errors. With structured concurrency, if one of the client calls fails, it cancels the other and throws. In particular if the second call fails, the first will be canceled right away and the function overall will throw.
In the case of the pure Mono
approach that you suggested, if we assume the first call succeeds in 5 seconds, but the second fails almost immediately, I believe you will still have to wait for the first call to complete before the second await can throw (but that's an assumption)xii
01/27/2022, 11:16 AMJoffrey
01/27/2022, 11:20 AMxii
01/27/2022, 11:20 AM