urql: Using `graphcache@5.0.0` or 6 the cache in the default storage is not loaded anymore on the first page load

After upgrading from 4 to 5 (or 6) @urql/exchange-graphcache doing some tests with a fake delay on the backend I discovered that when I refresh the page (F5 or Ctrl+R) the cache present in the IndexedDB is not used.

The REPL (with SvelteKit too) is here: https://codesandbox.io/p/sandbox/romantic-feather-xmc826

Steps:

  1. Go to https://xmc826-5173.csb.app/todos

  2. the todos are downloaded, showed and stored in the IndexedDB after 3 seconds of fake delay on the server resolver

  3. Click on the reload button in the navbar (or the browser’s one)

  4. The “Loading listStore…” message appears during the 3 fake delay seconds

  5. I expect instead to see the todos immediately (during the cache-and-network call which is still happening)

If I rollback only "@urql/exchange-graphcache" to "4.4.3" this “cold cache” behavior works again.

What could be causing the problem?

Thank you in advance.

Urql version

package.json

Validations

  • I can confirm that this is a bug report, and not a feature request, RFC, question, or discussion, for which GitHub Discussions should be used
  • Read the docs.
  • Follow our Code of Conduct

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 24 (22 by maintainers)

Most upvoted comments

6.0.4 doesn’t fix. @kitten is working on a solution: https://github.com/urql-graphql/urql/issues/3093#issuecomment-1528796774.

From https://github.com/urql-graphql/urql/issues/3199:

Describe the bug

I have an issue with duplicated requests (I remove the now deprecated dedupExchange: I read all CHANGELOGs and announcement issues like https://github.com/urql-graphql/urql/issues/3114).

If I use this code:

import { getContextClient, queryStore } from '@urql/svelte';

const currentPlayerStore = queryStore({
  client: getContextClient(),
  query: CurrentPlayerDocument,
  // the default requestPolicy is 'cache-first' // one request only, ok
  // requestPolicy: 'cache-and-network', // two requests, duplicated
  // requestPolicy: 'network-only' // THREE requests! Duplicated!
});

$: currentPlayer = $currentPlayerStore.data?.currentPlayer;

As you can read in the comments I isolated the issue: if I use the 'cache-first' policy it only send one request.

If I use the requestPolicy: 'cache-and-network' the requests are 2, duplicated, the same ones.

If I use the requestPolicy: 'network-only' the requests are 3 now! Crazy!

What am I doing wrong?

Reproduction

This repl is using your modified graphcache version that fixes https://github.com/urql-graphql/urql/issues/3093.

REPL: https://codesandbox.io/p/sandbox/issue-urql-6-duplicated-requests-x2y2ub

Steps:

  1. click on “Todos list”

  2. open the browser dev tools

  3. reload the page

  4. the requests are 2!

  5. If you use network-only in the list file the requests are 3 now

Urql version

I upgraded:

"devDependencies": {        
  "@graphql-codegen/cli": "3.3.1",
  "@graphql-codegen/typed-document-node": "4.0.1",
  "@graphql-codegen/typescript": "3.0.4", 
- "@urql/core": "2.6.1",  
+ "@urql/core": "4.0.7",  
  "@urql/devtools": "2.0.3",
- "@urql/exchange-graphcache": "4.4.3", 
+ "@urql/exchange-graphcache": "6.0.4", 
- "@urql/exchange-persisted-fetch": "1.3.4",  
+ "@urql/exchange-persisted": "4.0.0",
- "@urql/exchange-retry": "0.3.3",    
+ "@urql/exchange-retry": "1.1.1",    
- "@urql/svelte": "2.0.2",    
+ "@urql/svelte": "4.0.1",
- "graphql": "16.6.0",  
- "graphql-web-lite": "16.1.1000",
},

I haven’t really looked at this yet since I reckon a resolution will require a larger refactor and changes.

The reason why I believe(d) this is that the description of the issue implies that this is related to a different change where we ensured that the ssrExchange still works together with the offlineExchange.

This change however was made in 5.0.0: https://github.com/FormidableLabs/urql/pull/2612

Also #2945 relates to the replays after hydration , so I don’t see that exactly as responsible, and at most coincidentally changing behaviour.

So, that’s conflicting information to me right now, since I originally assumed that the issue is rather that, while offline or online, the offlineExchange currently does not replay queriy operations after rehydrating the cache from storage.

Then again, I’d assume that some of this relates to this check and failedQueue push: https://github.com/urql-graphql/urql/blob/8640fdbd5a63c7c1150b82a893924016d63309e7/exchanges/graphcache/src/offlineExchange.ts#L232

There we actually do queue failed queries. However, this could’ve only coincidentally made this work in the past, since it’d only work if onOnline is calling its callback after it succeeded.

Therefore the only logical conclusion is that flushQueue is called but either failedQueue isn’t properly populated with queries, or it doesn’t attempt to retry them. Another possibility is that the result eventually does come in properly but the initial fallback to cache-only is confusing.

Anyway, that’s my assumption from before and right now with the updated messages. I can see whether I’ll find time for this in the next 48h-ish or so. That said, the offlineExchange is only ~180 very “thin” lines of code without comments, so I can only encourage y’all to look into it and throw in some debugging of your own if you get to it sooner than myself 😇

@strewhella thank you very much for your comment!

This is the comparison between 5.0.8 and 5.0.9: @urql/exchange-graphcache@5.0.8…@urql/exchange-graphcache@5.0.9.

I think this PR is responsible for the problem: #2945.

@trcoffman can I ask you if you can detect the issue in the code and help us solve this problem?

I just forked your codesandbox and tried out 5.0.8, and this problem is still present. So i don’t think that my PR #2945 has anything to do with this. If you go back to 4.4.3 it works just the way you want it to.

I’m seeing the same issue after upgrading to @urql/exchange-graphcache@6.0.3. In a React Native app, when offline and using the cache-and-network request policy, the offlineExchange doesn’t return the cached data at all, data is always null, though stale is true.

Reverting to @urql/exchange-graphcache@5.0.8 resolves the problem, and cached data is returned as expected.

Me watching Kitten solve other people’s issues at lightning speed.

image