apollographql / apollo-kotlin-normalized-cache-incubating

Apollo Kotlin Incubating Normalized Cache
https://apollographql.github.io/apollo-kotlin-normalized-cache-incubating/
MIT License
9 stars 2 forks source link

Cache watching seems broken when writing ApolloStore operations #34

Open cvb941 opened 3 months ago

cvb941 commented 3 months ago

After some painful debugging, I noticed that the incubating cache does not emit data on watched queries when writing data using writeOperation, even when disabling all paging support. The same code seems to work when switched back to the production Apollo cache dependency.

I put up a quick sample here: https://github.com/cvb941/apollo-kotlin-normalized-cache-incubating/tree/main/samples/cache-watching-test

I added an update button that should increment all stars by one. It does it successfully, but the data is not refreshed on the screen (you can see the updated data when you restart the app after it fetches the cache).

val data = apolloClient.apolloStore.readOperation(RepositoryListQuery())
val updatedEdges = data.organization?.repositories?.edges?.map { edge ->
    edge?.let { e ->
        e.copy(
            node = e.node?.copy(
                repositoryFields = e.node.repositoryFields.copy(
                    stargazers = e.node.repositoryFields.stargazers.copy(
                        totalCount = e.node.repositoryFields.stargazers.totalCount + 1
                    )
                )
            )
        )
    }
}
val updatedData =
    data.copy(organization = data.organization?.copy(repositories = data.organization.repositories.copy(edges = updatedEdges)))
apolloClient.apolloStore.writeOperation(RepositoryListQuery(), updatedData)
image
martinbonnin commented 3 months ago

Many thanks for the reproducer 🙏 . This has indeed been a bit of an API challenge (see https://github.com/apollographql/apollo-kotlin/issues/5971) as writing the store is usually a synchronous operation but publishing needs to suspend to wait for possible (slow) consumers. To keep concerns separated, it's 2 APIs in the incubating cache:

In your example, you can do something like below:

val keys = apolloClient.apolloStore.writeOperation(RepositoryListQuery(), updatedData)
apolloClient.apolloStore.publish(keys)
cvb941 commented 3 months ago

Thank you for your response, it works now. Is the change mentioned somewhere right now? I must have missed it.

martinbonnin commented 3 months ago

This repository is pretty unstable, we do not keep a very strict changelog at the moment because things are still changing a lot, sorry.