apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.75k stars 650 forks source link

Add LRU Normalized Cache implementation #324

Closed BenSchwab closed 7 years ago

BenSchwab commented 7 years ago

We should ship a version of an in memory normalized cache. This could be used instead of SQL, or we could even ship a "double-layer" cache that would read from memory if possible.

Android has a LRU cache: https://developer.android.com/reference/android/util/LruCache.html Guava has memory caches: https://github.com/google/guava/wiki/CachesExplained

The Guava stuff looks really cool - but I'm not sure we need all of it's goodies. But not having to depend on an Android library is always a plus, even if we already have other Android dependencies.

For time based expiration to be useful, we would have to allow a user to pass in a "TTL" type parameter. This is something we will probably want for the SQL store. https://github.com/apollographql/apollo-android/issues/326

For size based expiration, we have the ability to accurately approximate cache size, because we are storing records whose fields are ultimately either a primitive or a reference.

@digitalbuddha I believe you recommended Guava. Would the right approach be to shade the Gauva cache / bring its files?

digitalbuddha commented 7 years ago

Already one step ahead of you. Here's nytimes guava cache lite. I painstakingly built it up by moving one file at a time https://github.com/NYTimes/Store/tree/develop/cache currently sits at about 400 methods.

BenSchwab commented 7 years ago

Great! So we can just add the dependency like compile com.nytimes.android:cache:CurrentVersion?

@sav007 @marwanad @brianPlummer Any objections to this dependency?

BenSchwab commented 7 years ago

There might actually be some value in pulling out all the cache implementations we ship with to a apollo-cache project. That way if someone doesn't want to use any caches, they won't get any of these dependencies.

digitalbuddha commented 7 years ago

Yup thats the dependency. Since Guava at v 19 was locked in as last one for Android until 21 we don't expect much changes to pull in from Guava but watch it carefully. As for the splitting project into multiple artifacts, I can do that once we are at a good point prior to release. Same thing was done with RxAndroid where it started as monolith and then was split. As long as we do separate packages for caches it should make refactoring easier later.

digitalbuddha commented 7 years ago

@BenSchwab I don't think we need to pull out to a separate project. How do you feel about just keeping different modules and artifacts similar to how the rx module is going to work. There is niceties in being 1 repo/project when it comes to refactoring or searching.

BenSchwab commented 7 years ago

Yep, totally agree