3

I'm using Guava's Loading Cache to cache the results of HTTP requests. Kotlin / KTOR provides an HTTP Client Library based on coroutines (i.e. non-blocking HTTP requests).

My problem is that the Loading Cache has no idea about suspending functions. The load function that I pass to the loading cache cannot suspend. So I am forced to do the HTTP requests inside a runBlocking call, eliminating the benefit of non-blocking calls completely.

My question is: is there a better way? How would you implement caching of coroutine results?

Martin Häusler
  • 6,544
  • 8
  • 39
  • 66
  • 1
    Consider using [Caffeine's](https://github.com/ben-manes/caffeine) `AsyncLoadingCache` and [convert](https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-jdk8) the coroutine to a `CompleteableFuture`. – Ben Manes Dec 01 '18 at 01:58
  • I found a nice solution using Caffeine: https://stackoverflow.com/a/55439143/4618331 – Sam Feb 25 '20 at 19:33

1 Answers1

7

You can put Deferred into guava's cache from coroutines async { ... }

Something like this

LoadingCache<Key, Deferred<Value>> = CacheBuilder.newBuilder()
    // ...
    .build(CacheLoader<Key, Deferred<Value>> { key ->
        someScope.async { computeMyValueSuspend(key) }
    })
Sergey Mashkov
  • 4,630
  • 1
  • 27
  • 24
  • That's an interesting idea! I think that might work, thanks! – Martin Häusler Nov 30 '18 at 13:52
  • would defining a single coroutine scope, like `val someScope = CoroutineScope(Dispatchers.Default)`, which I create once per cache be a suitable way to handle coroutine scope? – rrva Mar 29 '20 at 14:13