With Kotlin Coroutines I need to run two I/O work inside a try block at same time parallely without blocking each other.
And if any of the work fails, then it should be caught inside a single catch block.
Two operations are:
a) Continuously ping the server at a 10 second interval.
b) Make a network call with okhttp.
I need to cover these two operations inside a suspend function.
PSB code:
suspend fun sendAllRequests() {
try {
pingServer()
makeNetworkCall()
} catch(exception: CustomException) {
// Do some other work and throw exception to UI
throw RuntimeException("Custom Error")
}
}
suspend fun pingServer() {
job = GlobalScope.launch {
while(true) {
delay(10000) {
if(isPingSuccess) {
Log("Connection active")
} else {
Log("Connection Inactive")
job.cancel()
throw RuntimeException("Ping failed")
}
}
}
}
suspend fun makeNetworkCall() {
//This is a pseudo code just for explanation
okhttp.newCall().await()
onFailure -> throw Exception
}
The challenge with above approach is that it, only initiates the logic present inside function pingServer().
i.e. The function makeNetworkCall() is never triggered.
And if I wrap the first function inside a new coroutine scope like below:
then both job works fine, but the exception thrown by pingServer() is never caught in catch block.
try {
// With below logic, both functions are triggered
scope.launch { pingServer() }
makeNetworkCall()
} catch {
// but pingServer() failure never reaches here
// and makeNetworkCall() failure is properly captured here
}
How can I run the above two long running tasks parallely without blocking each other ?
How can I ensure that if any of them throws an exception, then it is caught inside the same catch block as shown above ?
Based on this article, an easy way to achieve what you are after is to not use
launchbut useasync. Then you can run yourmakeNetworkCall()and after thatawaiton your async deferred object catching the exception thereSomething like this:
Please also note: