[AC3]: Cache merges and race conditions causing data overwrites
See original GitHub issueIntended outcome:
Not 100% sure what’s going on here, but I’m following instructions on merging objects in cache, trying to achieve similar behaviour to AC2.
Given I have multiple queries against the same object, I’m looking to ensure the query results from the same query are merged together in cache, even though the queries don’t reference the ID field.
query Attitude($connection: ID!) {
connection(connectionId: $connection) {
device {
attitude {
roll
pitch
heading
}
}
}
}
query FcSummary($connection: ID!) {
connection(connectionId: $connection) {
device {
arming {
disabledFlags
}
power {
voltage
mahDrawn
amperage
}
rc {
rssi
}
}
}
}
Cache setup:
cache.policies.addTypePolicies({
Query: {
fields: {
connection: {
keyArgs: ["connectionId"],
merge: (existing, incoming, { mergeObjects }) => {
return mergeObjects(existing, incoming);
},
},
},
},
Connection: {
fields: {
device: {
merge: (existing, incoming, { mergeObjects }) => {
return mergeObjects(existing, incoming);
},
},
},
}
});
Actual outcome:
Some sort race condition seems to be taking place when the caches are merged together. The result of the “Attitude” query is causing the result of the “Summary” query to be overwritten.
Here is an example log of this, where I am logging the cache merges in device
:
- FcSummary is merged with existing cache:
(2020-04-19T23:23:42.929Z) existing: {
"__typename": "FlightController",
"sensors": [
0,
5
],
"status": {
"__typename": "Status",
"cycleTime": 552,
"i2cError": 7,
"cpuload": 20
}
}
client.ts:55 (2020-04-19T23:23:42.929Z) incoming: {
"__typename": "FlightController",
"arming": {
"__typename": "Arming",
"disabledFlags": [
2,
15
]
},
"power": {
"__typename": "Power",
"voltage": 0,
"mahDrawn": 0,
"amperage": 0
},
"rc": {
"__typename": "RC",
"rssi": 144
}
}
client.ts:56 (2020-04-19T23:23:42.929Z) merged: {
"__typename": "FlightController",
"sensors": [
0,
5
],
"status": {
"__typename": "Status",
"cycleTime": 552,
"i2cError": 7,
"cpuload": 20
},
"arming": {
"__typename": "Arming",
"disabledFlags": [
2,
15
]
},
"power": {
"__typename": "Power",
"voltage": 0,
"mahDrawn": 0,
"amperage": 0
},
"rc": {
"__typename": "RC",
"rssi": 144
}
}
- Very closely after, “Attitude” is merged. However, it seems the results from the previous merge have not yet reached the cache, and the previous “existing” is used:
(2020-04-19T23:23:42.937Z) existing: {
"__typename": "FlightController",
"sensors": [
0,
5
],
"status": {
"__typename": "Status",
"cycleTime": 552,
"i2cError": 7,
"cpuload": 20
}
}
client.ts:55 (2020-04-19T23:23:42.938Z) incoming: {
"__typename": "FlightController",
"attitude": {
"__typename": "Attitude",
"roll": -6.6,
"pitch": 1.6,
"heading": 108
}
}
client.ts:56 (2020-04-19T23:23:42.938Z) merged: {
"__typename": "FlightController",
"sensors": [
0,
5
],
"status": {
"__typename": "Status",
"cycleTime": 552,
"i2cError": 7,
"cpuload": 20
},
"attitude": {
"__typename": "Attitude",
"roll": -6.6,
"pitch": 1.6,
"heading": 108
}
}
And as you can see the existing cache data is not up to date with the previous merge, so the second merge ends up overwriting the first. This means that the data for the “Summary” is never resolved and so the data doesn’t get rendered.
How to reproduce the issue: Attempted a code sandbox to reproduce, but could not get a reproduction outside of my repo as it behaves correctly: https://codesandbox.io/s/gracious-tesla-4pc2p
Using a naive merge function ({...existing, ...incoming}
), this issue is still present in my codebase.
If I roll back to beta-30
(this is the latest version I can get it to work on) then this issue is fixed against my codebase, which means something was changed between beta-30
and beta-31
to break this for me.
The commit which seems to be the only cause is: https://github.com/apollographql/apollo-client/commit/87b9fd250fd73c5c14409dc461bc2941167df2fe, which looks synchronous to me.
I am totally stumped at this to be honest. My only option for now is to make my device
object singleton (keyFields: []
) which makes the query results merge correctly.
FYI the queries merge correctly when I add the ID
field to all my queries, but I’m not looking to solve it that way as the docs seem to suggest what I am doing should work.
Versions
@apollo/client@beta-43
down to @apollo/client@beta-31
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
Seems to be solved in later versions, forgot to close this!
Let us know if this is still a concern with
@apollo/client@latest
- thanks!