Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💧 first drop for a SQLite backend that stores when each field was last updated #4104

Merged
merged 45 commits into from May 19, 2022

Conversation

martinbonnin
Copy link
Contributor

@martinbonnin martinbonnin commented May 13, 2022

See #3566

First drop for a SQLite backend that stores when each field was last updated. It introduces a new SQLite table that stores Records in a binary format that also holds the last updated timestamp.

This allows to throw a cache miss when a given field is older that a configured max-age

    val client = ApolloClient.Builder()
        .normalizedCache(
            normalizedCacheFactory(),
            TypePolicyCacheKeyGenerator,
            MaxAgeCacheResolver(10) // Allow 10s for the max Age
        )
        .serverUrl("https://...")
        .build()

    val records = query.normalize(data, CustomScalarAdapters.Empty, TypePolicyCacheKeyGenerator).values

    client.apolloStore.accessCache {
      // store records 11s in the past
      it.merge(records, cacheHeaders(currentTimeMillis()/1000 - 11))
    }

    try {
      client.query(GetUserQuery()).fetchPolicy(FetchPolicy.CacheOnly).execute()
      fail("An exception was expected")
    } catch (e: CacheMissException) {
      assertTrue(e.age != null) // Age will be 11s
    }

Next steps:

  • add more tests
  • make the maxAge configurable per-type/per-field programmatically
  • make the maxAge configurable per-type/per-field declaratively
  • add benchmarks

@netlify
Copy link

netlify bot commented May 13, 2022

Deploy Preview for apollo-android-docs canceled.

Name Link
🔨 Latest commit 122147a
🔍 Latest deploy log https://app.netlify.com/sites/apollo-android-docs/deploys/62853e63a839d400090d01ab

Copy link
Contributor

@BoD BoD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On thing that I'm not entirely sure I understand: the date stored along with fields - with the MaxAgeCacheResolver they're meant to represent the time at which they were received, right? But with a different Resolver, they could also represent an expiration date in the future (whose value could come from the server), right? So it is a generic date - its usage can adapt to needs?

@martinbonnin
Copy link
Contributor Author

One thing that I'm not entirely sure I understand: the date stored along with fields - with the MaxAgeCacheResolver they're meant to represent the time at which they were received, right? But with a different Resolver, they could also represent an expiration date in the future (whose value could come from the server), right? So it is a generic date - its usage can adapt to needs?

Excellent question. At the moment it's mostly the receive time. We could store the expiration time too I guess. It wouldn't be too hard I think. Something I want to improve is to make sure a given database is always open with the same assumption (blob vs json, date vs expire). I'll suggest something

@martinbonnin
Copy link
Contributor Author

Also closes #3758

@martinbonnin martinbonnin force-pushed the blob-store branch 2 times, most recently from e284351 to 383a03c Compare May 18, 2022 14:42
build.gradle.kts Outdated Show resolved Hide resolved
martinbonnin and others added 3 commits May 18, 2022 20:11
Co-authored-by: Benoit Lubek <BoD@JRAF.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants