Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

(docs) - Replace "Under the hood" page

+66 -44
docs/assets/commutative-layers.png

This is a binary file and will not be displayed.

+62
docs/graphcache/normalized-caching.md
··· 446 446 normalized cache is expected to perform. 447 447 448 448 [Read more about writing cache updates on the "Cache Updates" page.](./cache-updates.md) 449 + 450 + ## Deterministic Cache Updates 451 + 452 + Above, in [the "Storing Normalized Data" section](#storing-normalized-data), we've talked about how 453 + Graphcache is able to store normalized data. However, apart from storing this data there are a 454 + couple of caveats that many applications simply ignore, skip, or simplify when they implement a 455 + store to cache their data in. 456 + 457 + Amongst features like [Optimistic Updates](./cache-updates.md#optimistic-updates) and [Offline 458 + Support](./offline.md), Graphcache supports several features that allow our API results to be more 459 + unreliable. Essentially we don't expect API results to always come back in order or on time. 460 + However, we expect Graphcache to prevent us from making "indeterministic cache updates", meaning 461 + that we expect it to handle API results that come back in a random order and delayed gracefully. 462 + 463 + In terms of the ["Manual Cache Updates"](#manual-cache-updates) that we've talked about above and 464 + [Optimistic Updates](./cache-updates.md#optimistic-updates) the limitations are pretty simple at 465 + first and if we use Graphcache as usual we may not even notice them: 466 + 467 + - When we make an _optimistic_ change, we define what a mutation's result may look like once the API 468 + responds in the future and apply this temporary result immediately. We store this temporary data 469 + in a separate "layer". Once the real result comes back this layer can be deleted and the real API 470 + result can be applied as usual. 471 + - When multiple _optimistic updates_ are made at the same time, we never allow these layers to be 472 + deleted separately. Instead Graphcache waits for all mutations to complete before deleting the 473 + optimistic layers and applying the real API result. This means that a mutation update cannot 474 + accidentally commit optimistic data to the cache permanently. 475 + - While an _optimistic update_ has been applied, Graphcache stops refetching any queries that contain 476 + this optimistic data so that it doesn't "flip back" to its non-optimistic state without the 477 + optimistic update being applied. Otherwise we'd see a "flicker" in the UI. 478 + 479 + These three principles are the basic mechanisms we can expect from Graphcache. The summary is: 480 + **Graphcache groups optimistic mutations and pauses queries so that optimistic updates look as 481 + expected,** which is an implementation detail we can mostly ignore when using it. 482 + 483 + However, one implementation detail we cannot ignore is the last mechanism in Graphcache which is 484 + called **"Commutativity"**. As we can tell, "optimistic updates" need to store their normalized 485 + results on a separate layer. This means that the previous data structure we've seen in Graphcache is 486 + actually more like a list, with many tables of links and entities. 487 + 488 + Each layer may contain optimistic results and have an order of preference. However, this order also 489 + applies to queries. Since queries are run in one order but their API results can come back to us in 490 + a very different order, if we access enough pages in a random order things can sometimes look rather 491 + weird. We may see that in an application on a slow network connection the results may vary depending 492 + on when their results came back. 493 + 494 + ![Commutativity means that we store data in separate layers.](../assets/commutative-layers.png) 495 + 496 + Instead, Graphcache actually uses layers for any API result it receives. In case, an API result 497 + arrives out-of-order, it sorts them by precedence — or rather by when they've been requested. 498 + Overall, we don't have to worry about this, but Graphcache has mechanisms that keep our updates 499 + safe. 500 + 501 + ## Reading on 502 + 503 + This concludes the introduction to Graphcache with a short overview of how it works, what it 504 + supports, and some hidden mechanisms and internals. Next we may want to learn more about how to use 505 + it and more of its features: 506 + 507 + - [How do we write "Local Resolvers"?](./local-resolvers.md) 508 + - [How to set up "Cache Updates" and "Optimistic Updates"?](./cache-updates.md) 509 + - [What is Graphcache's "Schema Awareness" feature for?](./schema-awareness.md) 510 + - [How do I enable "Offline Support"?](./offline.md)
-44
docs/graphcache/under-the-hood.md
··· 1 - --- 2 - title: Under the hood 3 - order: 5 4 - --- 5 - 6 - # Under the hood 7 - 8 - Graphcache has a couple of hidden features behind the scenes, that handle how it deals with certain edge cases. 9 - Being aware of these features and edge cases makes it easier to define best practices and to avoid pitfalls. 10 - 11 - Most of these hidden features and mechanisms in this section exist to ensure consistent behavior for Graphcache's (future) offline and persistence features. 12 - 13 - ## Commutativity 14 - 15 - By default the cache ensures that results from the API are applied commutatively. 16 - 17 - Commutativity is a guarantee that means that Graphcache will attempt to keep the order of cache changes consistent, when results arrive out-of-order from the API, for instance due to network latency. When a query is dispatched first and another second, their results can still arrive in reverse, but Graphcache will still make sure that the cache results are applied in order, as if the results arrived in the right order. 18 - Let's look at an example to understand this. 19 - Suppose our application queues up two queries, an `authorsQuery` and a `todosQuery`. 20 - 21 - We dispatch the `todosQuery` first and the `authorsQuery` later, but because of network latency the `authorsQuery`'s result arrived before the `todosQuery`'s result. 22 - The cache will put the out-of-order result from the `authorsQuery` onto a layer until the other result arrives. 23 - This layer contains the out-of-order result's data, but hasn't been committed yet to the permanent in-memory data. 24 - When the `todosQuery` does arrive and all out-of-order results have been stored on layers, the cache will start committing in order to ensure the actual data is consistent. 25 - This layering approach means that Graphcache is able to temporarily reorder results as they arrive, ensuring that the results don't overwrite each other in a random order. 26 - 27 - ## Optimistic results & refetches 28 - 29 - We've previously learned about [how to create "Optimistic Updates" in an earlier section.](./cache-updates.md#optimistic-updates) 30 - Optimistic updates can temporarily update cached data after incoming mutations, which will trigger on screen queries to update. 31 - However, if we also use [the `cache-and-network` request policy](../concepts/document-caching.md#request-policies) at the same time, some queries can refetch and overwrite our optimistic data, 32 - causing an unintended state where the intended optimistic update is destroyed. 33 - Such an unintended refetch can also happen if after an optimistic update a query is refetched when it’s not or 34 - only partially available in the cache. 35 - 36 - To prevent this, Graphcache will temporarily pause refetches that may overwrite optimistic updates. 37 - Once all mutations with optimistic updates complete however, all results will be applied at once, 38 - and refetched that may update the mutation data will be rerun. 39 - 40 - Let's look at an example. Suppose our app has a list of entities (for instance `Todo`s). 41 - We've written an optimistic update so that when the user deletes an item from the list, we make it disappear immediately. 42 - Usually, if the list is using a query with `cache-and-network`, this means that the optimistic update would automatically trigger a refetch of the list, which would make the deleted item reappear, although it shouldn't. 43 - 44 - To prevent this, Graphcache waits for the mutation to complete instead, as it detects that the query overlaps with the optimistic update, and retriggers the refetch only when all mutations have completed.
+4
packages/site/static.config.js
··· 82 82 path: '/docs/graphcache/computed-queries', 83 83 redirect: '/docs/graphcache/local-resolvers', 84 84 }, 85 + { 86 + path: '/docs/graphcache/under-the-hood', 87 + redirect: '/docs/graphcache/normalized-caching', 88 + }, 85 89 ], 86 90 };