Timeouts in Kotlin
Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Kotlin is straightforward using coroutines and withTimeout function.
import kotlinx.coroutines.*
import kotlin.time.Duration.Companion.seconds
suspend fun main() = runBlocking {
// For our example, suppose we're executing an external
// call that returns its result after 2s. We'll use a
// suspending function to simulate this delay.
suspend fun fetchResult1(): String {
delay(2.seconds)
return "result 1"
}
// Here we use `withTimeout` to implement a timeout.
// If the operation takes more than the allowed 1s,
// it will throw a TimeoutCancellationException.
try {
val result = withTimeout(1.seconds) {
fetchResult1()
}
println(result)
} catch (e: TimeoutCancellationException) {
println("timeout 1")
}
// If we allow a longer timeout of 3s, then the call
// will succeed and we'll print the result.
suspend fun fetchResult2(): String {
delay(2.seconds)
return "result 2"
}
try {
val result = withTimeout(3.seconds) {
fetchResult2()
}
println(result)
} catch (e: TimeoutCancellationException) {
println("timeout 2")
}
}Running this program shows the first operation timing out and the second succeeding.
$ kotlinc -cp kotlinx-coroutines-core.jar timeouts.kt -include-runtime -d timeouts.jar
$ java -jar timeouts.jar
timeout 1
result 2In this Kotlin version:
We use Kotlin Coroutines to handle asynchronous operations. The
runBlockingfunction is used to bridge between the regular and coroutine world.Instead of channels and goroutines, we use suspending functions to simulate our delayed operations.
The
selectstatement is replaced with thewithTimeoutfunction, which automatically throws aTimeoutCancellationExceptionif the operation doesn’t complete within the specified time.We use
try-catchblocks to handle the timeout exceptions, printing either the result or the timeout message.The
time.Sleepcalls are replaced withdelayfunction calls, which are more idiomatic in Kotlin coroutines.
This approach provides a clean and straightforward way to implement timeouts in Kotlin, leveraging the power of coroutines.