-
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
readQuery after cache evict #6325
Comments
@danReynolds can you confirm which |
@hwillson this is on 3.0.0-beta.49. I think the read not supporting partial data is intended behavior, I'm just not sure how we can access fields containing dangling refs then. It'd be nice if |
@hwillson Here's a commit off latest master demonstrating the problem: danReynolds@d2a09a7, if you run it you'll see it errors out with the dangling reference problem. The goal is to be able to make the query valid again by removing the evicted reference. |
What about removing entities from queries before evicting them? |
ah because that's more manual effort than necessary, any watch queries containing an entity that has been evicted will automatically refetch if |
Question: When cache.read{Query,Fragment} encounters a dangling reference (one that does not currently refer to any normalized entity object in the cache), should the cache behave as if the (nonexistent) target of the reference was an empty object, and report any requested fields as missing, or should the cache generate some other kind of error that reflects the the absence of the whole object? I think we could answer this question either way, but I'm leaning towards the first option. Note: it's normal for the cache to end up with dangling references when whole entity objects are evicted, or when a reference is created (e.g. by toReference) without writing any data into the cache. Cleaning up dangling references is a tricky problem, requiring application-level reasoning, and not even always desirable, since the data could always come back into the cache later, restoring the validity of the reference. Previously, I thought it would be helpful to distinguish between the absence of an entity object and the object simply being empty, but I no longer think this distinction (which only affected the wording of the MissingFieldError description) matters very much, and we can simplify everything by adopting the following policy: > During cache reads, a dangling Reference should behave as much as possible like a Reference to an entity object that happens to contain zero fields. I'm optimistic this policy may help with issues like #6325. At the very least, this policy means there's now only one kind of MissingFieldError, which should reduce confusion.
Shortly after the AC3.0 release, we are hoping to introduce some sort of field policy configuration to specify what happens when references contained by a field no longer point anywhere. For example, the policy could control whether the field itself gets removed, or what happens to lists that contain dangling references. I think the default behavior will continue to be leaving the dangling references untouched, but you could opt into fancier behavior where it's useful. It's definitely tempting to do this work as part of Note: with #6365, I am hoping to establish a policy that dangling references behave as much as possible like references to empty objects, so you won't see these |
) Question: When cache.read{Query,Fragment} encounters a dangling reference (one that does not currently refer to any normalized entity object in the cache), should the cache behave as if the (nonexistent) target of the reference was an empty object, and report any requested fields as missing, or should the cache generate some other kind of error that reflects the the absence of the whole object? I think we could answer this question either way, but I'm leaning towards the first option. Note: it's normal for the cache to end up with dangling references when whole entity objects are evicted, or when a reference is created (e.g. by toReference) without writing any data into the cache. Cleaning up dangling references is a tricky problem, requiring application-level reasoning, and not even always desirable, since the data could always come back into the cache later, restoring the validity of the reference. Previously, I thought it would be helpful to distinguish between the absence of an entity object and the object simply being empty, but I no longer think this distinction (which only affected the wording of the MissingFieldError description) matters very much, and we can simplify everything by adopting the following policy: > During cache reads, a dangling Reference should behave as much as possible like a Reference to an entity object that happens to contain zero fields. I'm optimistic this policy may help with issues like #6325. At the very least, this policy means there's now only one flavor of MissingFieldError, which should reduce confusion.
@benjamn So with these changes a A simple example being a CarsQuery using
|
@benjamn Haivng policies to affect how dangling references are handled sounds promising (and including it also as part of GC makes sense to me). I agree with the above though in preferring cache misses come back with |
I think this change has been reverted and dangling references are treated the same way they were before - throwing error. |
I'm still getting back an empty object when I have I was only |
Quick updates: Yes, #6365 was reverted—sorry for that distraction. However, please have a look at #6454 (which implements #6425 (comment)) for a more automatic (and I think pretty elegant!) solution to the problem of dangling references in lists. Avoiding manual updates after eviction is an area of ongoing investigation and improvement, but I believe/hope these changes make a meaningful difference. |
Closing because the original example provided by @danReynolds should now work without any manual effort (the list is automatically filtered using the |
Hello! I have a question about how eviction of normalized objects interacts with queries that already had references to those objects. For example, if I were to do the following:
I could then access that data like this:
but if I then evict the entity that the query contains:
then subsequent calls to
readQuery
foremployeesQuery
fail with errorDangling reference to missing Employee:1 object
and the query seems to now just be completely inaccessible and there doesn't seem to be a way to clear out the bad ref that it holds so that readQuery will work again. Is there something I'm missing?it makes sense that the query would now have missing data, but there seems to be no way to remove it from the query since first I'd need to call
readQuery
to get what's currently there and thenwriteQuery
to remove the dangling object. If it was able to return partial data then it would work, but reads prohibit that here:apollo-client/src/cache/inmemory/readFromStore.ts
Line 108 in a18ee7e
This forces users to have to refetch queries that have had entities evicted, which can introduce unnecessary network burden if instead the user knows they can remove the evicted entity from that query.
Let me know what I should do to enable accessing or updating those stale queries, thanks!
The text was updated successfully, but these errors were encountered: