apollo-kotlin
apollo-kotlin copied to clipboard
Query watcher re-emitting old value after caches are cleared
I'm facing some weird behavior, which I'm not even sure if it's a bug or intended behavior. If the second, I'm curious what's the reasoning.
I have two different queries, and (probably related) each of them contains objects of the same types: QueryOne fetches [A]
and [B]
, and QueryTwo also fetches [A]
and [B]
. What I'm doing then is I:
- watch
QueryOne
- clear caches (HTTP cache and normalized cache)
- watch
QueryTwo
On the third step, when watching QueryTwo
, the first watcher for QueryOne
emits again, with the previous data. This is pretty unexpected, because it happens even when there are no common items between both queries. In particular it happens when all the returned lists in both queries are empty.
Is this simply lack of optimization, or a bug? Previously I expected that QueryOne
might emit again if QueryTwo
actually updates some object returned by QueryOne
, but with empty lists I'm not so sure. Might it be because both queries return the same root, under which [A]
and [B]
are then nested?
Sorry for unclear example, but as usual this happens with our production schema which I'm not sure I can share :\
This is with Apollo 1.2.3
Each query watchers internally builds set that called dependentKeys
(com.apollographql.apollo.api.Response#dependentKeys). These are keys that will trigger any query watcher when some other query touched them
The behaviour you see is totally legit as seems like in your example QueryOne
and QueryTwo
have intersection of dependentKeys
. Means when you trigger second query it will first fetch data from server, put to cache, and that will trigger QueryOne
watcher to refetch (when query writes to cache it notifies what cache keys were modified to trigger watchers to referesh)
I expected something like this. So is this also what's happening when both queries return empty lists? Since in that case none of the returned objects (in both queries) even have an ID for the normalized cache, so I'd expect the first query to actually never emit again. Unless the top-level common object (also without an ID) triggers this new emission as well. Only if this happens, we'd be emitting unnecessarily all the time :/
https://github.com/apollographql/apollo-android/blob/master/apollo-runtime/src/main/java/com/apollographql/apollo/internal/RealApolloQueryWatcher.java#L40
Yeah and this behaviour was added after fixing this issue https://github.com/apollographql/apollo-android/issues/822