-
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
Infinite loop caused by Type Policy with read function #7028
Comments
@timothyarmes Can you put this setup into a reproduction? That will help us give you the right advice without guessing (though I can keep guessing if a repro is not feasible). As an initial note, that |
Hi Ben. I'll try to find time to create a repo. You're right, the DatePolicy class instance won't work. |
Hey @timothyarmes Thanks for sharing this I was having the exact same issue. Good luck :) |
Gentle reminder that we’re looking for reproductions. I greatly prioritize any issue which I can run, and I got a lot of issues on my plate at the moment. If not, I will get to this soon no worries 😇 |
I'm hitting the same issue, just spent 3 hours trying to debug. The trigger seems to be a mutation using an update function to merge a field onto a type with a read function specified on the type policy. |
This took a lot of trial/error, but for me it was printing out the merge(existing = [], incoming, options) {
const merged = _.uniqBy([...existing, ...incoming], '__ref')
console.log('Merged audioPosts', {
existing,
incoming,
options,
variables, // ADDING `: options.variables,` FIXED THE ISSUE (along with a React Native printing error)
merged,
}) EDIT: Nevermind, still getting 7 of the same queries. It only makes 1 request and the rest hit cache, but the merge is annoying/slow. |
Your UserType or fields within UserType (createdAt) probably don't have an ID for Apollo to deduplicate the data in the cache. What is probably happening is that Apollo saves the data of the logged User in the cache and the other request that lists the users modifies the data of this logged user (with different data) forcing a cache update. A single missing field in the cache for the query querying the logged in user will cause a new request. The infinite loop happens because the UserType data in separate queries are different and each request updates the cache with the expected format. This comment reinforces my point. You can confirm that you are having a cache update on the user type using the apollo client devTools extension in the cache tab. Complement Apollo Client identifies similar data from different requests by associating the field type plus the object id. It may be that a schema of a request has an id (or the field used to reference it) and the other request that has the same type does not have this id. The first request adds the id and the second modifies the cache without the id. When the cache data modifies it calls again the first request and modifying the cache again calls the second. Infinite loop. |
Hi everyone 👋 In case it's helpful, we have a CodeSandbox and forkable GitHub repo for creating reproductions, which would greatly aid in prioritizing/assessing this issue. Thanks! |
I experienced the same issue today. Adding a read function to a field would cause two queries to be fetched in an infinite loop.
The backend returned the same id for |
It started happening again with different queries, now I realised that the infinite loop also happens if there are some queries getting data from types that don't have ID where there is no merge function defined in the cache, if the queries override the data of each other. |
@alessbell |
@benjamn I would greatly appreciate it if you have time to look at this issue and my reproduction example above, this is blocking us from using custom cache read functions as I can't risk this happening in production. |
Hi @marco2216, I've taken a look at this and believe #11430 might get closer to solving this problem. The problem of potential feuds between queries is very complex, though, so this will likely need a lot more investigation before we can get it in - just as a fair warning. |
My app has a
User
type for which I've defined a type policy:I also have a query to fetch the currently logged in user, and a HOC is used to fetch that user and render sub components.
Now, in a subcomponent I'm running a query which fetches a set of users:
When that query returns the currently logged-in user as part of the
users
list, the code enters into an infinite loop.The fields returned for the currently logged in user are merged into the user object in the cache. Despite the fact that these fields have not changed the value of that user object, this causes the 'me' query to rerun, which reruns the 'mission' query above, which leads to the infinite loop.
However, if I remove the
createdAt
field from the Type Policy for the User object then everything works.I thought that I be able to work around the issue be returning the exact same parsed date object when the date doesn't change:
And using this class in the Type Policy:
however that doesn't solve the problem.
If however the read function returns the object unchanged then the loop is avoided:
So, it seems that when a read function that returns a value other than that passed in will force the query to re-run.
Versions
System:
OS: macOS 10.15
Binaries:
Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
Yarn: 1.19.2 - /usr/local/bin/yarn
npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm
Browsers:
Chrome: 85.0.4183.102
Firefox: 77.0.1
Safari: 13.0.2
npmPackages:
@apollo/client: ^3.2.0 => 3.2.0
apollo-link-logger: ^1.2.3 => 1.2.3
apollo-server-express: ^2.17.0 => 2.17.0
The text was updated successfully, but these errors were encountered: