urql-graphql / urql

The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
https://urql.dev/goto/docs
MIT License
8.65k stars 452 forks source link

Stale is `false` even if the `cache-and-network` call is pending #3263

Closed frederikhors closed 1 year ago

frederikhors commented 1 year ago

Describe the bug

I'm so glad you answered, @kitten and say the problem is in my code because this means I can solve it independently and I don't have to bother you guys anymore.

But I'm opening this issue because after your answer I tried to further investigate and I still cannot understand where is the issue in my code.

The only code I'm using here is:

const client = getContextClient();

$: listStore = queryStore({
  client,
  query: TODOS_QUERY,
  variables: { input: { first: 100 } },
  requestPolicy: "cache-and-network",
});

Steps

  1. Start the backend visiting: https://codesandbox.io/p/sandbox/h1pcl

  2. Open the frontend reproduction: https://codesandbox.io/p/sandbox/mtplzm

  3. Go to the "Todos list" page and wait for todos list to be rendered

  4. Now the cache is fullfilled with todos

  5. Click on the "Reload" button

  6. As you can see the list is immediately loaded (from the cache), a call is pending (because of cache-and-network), but the stale flag is false!

Do you still believe this is expected behaviour?

More thoughts

I think this is the cause for the custom "pending requests" exchange issue too.

Using @urql/exchange-graphcache version 4.4.3 everything works as expected: stale is true during that pending call.

The gif

issue

Reproduction

https://codesandbox.io/p/sandbox/mtplzm

Urql version

"@urql/core": "4.0.10",
"@urql/exchange-graphcache": "6.1.1",
"@urql/exchange-persisted": "4.0.0",
"@urql/exchange-retry": "1.2.0",
"@urql/svelte": "4.0.2",

Validations

kitten commented 1 year ago

Codesandbox is notoriously bad at deduplicating imports and following general package manager behaviour. If you replace your import of the fetchExchange with:

import { fetchExchange } from '@urql/core';

You can see the the HTTP request is correctly cancelled.

As stated before, cancelled or not, an HTTP requests don't map 1:1 to operations. An HTTP request being active/pending does not mean an operation is and vice-versa.


As per prior responses, please stick to ongoing threads, since in the ongoing thread I've also explained this:

Furthermore, you're confusing operations with network requests. Not all operations result in a network request. So, if you're tracking active operations and pending operations, operations are only pending if they don't receive a result synchronously, since this easily maps to caching behaviour.

This is a duplicate issue, and further questions/comments should be directed at #3234.

Due to repeated behaviour, please also see this as a kind warning of a Code of Conduct violation. No matter you having been kind or polite, if you don't follow professional conduct and are respectful of the time we can or cannot spend or deem appropriate to some issues, as you've been warned to in the past, I'm forced to issue you with a temporary timeout ban.

I can only dedicate so much time to this, but if an issue is not deemed to be a bug and instead a usage issue or a misunderstanding and this has been communicated multiple times, the same question will not lead to a different answer. Expecting a different outcome from the same situation is unreasonable, no matter how you phrase it. Only different reproductions, arguments, or discussions can lead to different outcomes.

However, I'll repeat this, prior threads and PR have made the change of expected behaviour here clear, after we — as discussed — agreed and identified that the offlineExchange regressed on past queuing behaviour. Now, the prior behaviour has been restored and all normal recommendations apply, as before.

Since this is a public forum and publicly visible, and may be read by other people who this may not concern, I will remove the above texxt from the comment past the divider line in a few hours, so it's not as publicly visible.