-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Multiple (3) lines of defense against merging { __ref }
objects into normalized StoreObject
entities
#8505
Multiple (3) lines of defense against merging { __ref }
objects into normalized StoreObject
entities
#8505
Conversation
{ __ref }
objects into entity objects{ __ref }
objects into StoreObject
entity objects
{ __ref }
objects into StoreObject
entity objects{ __ref }
objects into normalized StoreObject
entities
No test case? |
@brainkim Working on a test! Let me know if you have any reproductions from your investigation yesterday, and I'll try to include them as regression tests. |
Sorry I don’t have a handle on the exact schema query/eviction pattern from Apollo Studio which was causing the Account to be a reference or whatever. If you’d like me to figure that out, let me know. |
@brainkim Studio isn't doing anything wrong! Ultimately, Studio will benefit from #7778 because they have code that previously (using AC v3.3.7) would replace an existing |
f93f4f1
to
4832e87
Compare
@brainkim Alright, I've added separate regression tests to each commit. |
PR #7778 (first released in
@apollo/client@3.4.0-beta.12
) allowedmerge: true
to combineReference
objects (which refer to normalizedStoreObject
entities by ID) with non-normalizedStoreObject
objects.When these mixed
Reference
/StoreObject
merges happen (e.g. in themergeObjects
function), theStoreWriter#applyMerges
method returns aReference
rather than aStoreObject
, which was a new possibility not adequately handled by the calling code in PR #7778. In particular,applyMerges
returning aReference
could result in callingstore.merge(dataId, fields)
whenisReference(fields)
, allowing__ref
properties to end up as fields in the normalizedStoreObject
. These stray__ref
properties could later confuse theEntityStore
garbage collector into not traversing the other properties of theStoreObject
(because the object appears to be aReference
), potentially misidentifying any unreached references as unreachable, and thus inappropriately deleting them from the store.This PR solves these problems in three independent ways:
StoreWriter#applyMerges
returns aReference
, we now assume its fields have already been updated in the store, and avoid merging theReference
object usingstore.merge(dataId, fields)
.EntityStore#findChildRefIds
to continue traversing other properties of objects that appear to have__ref
properties, just in case there has been an accidental merge.Reference
arguments inEntityStore#merge
by converting them to their string IDs, which are well-handled by themerge
method already. This shouldn't happen now thanks to 1, but provides a foolproof backup plan.