I'm currently trying to create a caching layer around a web request. So far I've written:
class Repository(private val webServices: WebServices) {
private var cachedItems: List<Item>? = null
suspend fun getItems(): List<Item> {
cachedItems?.let { return it }
val items = withContext(Dispatchers.IO) { webServices.getItems() }
cachedItems = items
return items
}
}
My concern is what will happen when getItems()
is invoked by two callers simultaneously. Ideally, I'd only want one web request to occur. What's the recommended approach for dealing with this issue when using coroutines?
Kotlin coroutines & structured concurrency In Kotlin, we can create coroutines using builders such as launch and async , which return a Job instance. This Job may further contain nested coroutine builders that create children Job instances that are computed concurrently.
coroutines library provides support for using multiple threads. It is a separate branch for the reasons listed in the future concurrency model blog post. However, you can still use the multithreaded version of kotlinx.
Channel class kotlinx. coroutines library is thread-safe. It is designed to support multiple threads.
Similar to threads, coroutines can run in concurrently, wait for, and communicate with each other with the difference that creating them is way cheaper than threads.
Here's a simple solution.
class Repository(private val webServices: WebServices) {
private val cachedItems = async(Dispatchers.IO, start = CoroutineStart.LAZY) {
webServices.getItems()
}
suspend fun getItems(): List<Item> {
return cachedItems.await()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With