Urql: RFC: Optimistic Mutation improvements for Graphcache

Created on 23 Apr 2020  路  4Comments  路  Source: FormidableLabs/urql

Summary

There are several cases that we can make more intuitive for users without sacrificing performance or usability (or preventing additional use-cases) that would enable users to write simpler updater code for Graphcache.

In essence there are two existing issues around optimistic mutations:

  • When cache-and-network is used or when a result is partial, a query result may be fetched by Graphcache that overwrites optimistic updates. These can be summarised as result.stale === true results. Optimistic Updates shouldn't be invalidated unnecessarily.
  • When multiple optimistic updates have been written in parallel for the same data (e.g. a list), once a mutation settles and the mutation result is written, an updater may see some of the other mutation's optimistic updates and accidentally commit them in that update making them permanent. Optimistic Updates should never be committed to permanent data accidentally.

Proposed Solution

1. Block refetches that overlap Optimistic Updates

The solution to the first problem is to block calling cache.reexecuteOperation on queries whose dependencies overlap with any optimistically written updates.

This can be done by storing dependencies of any ongoing optimistic update, and checking whether a stale query (where result is marked as result.stale = true) overlaps with these "blocked dependencies." If they do, the query isn't refetched.

When the optimistic result settles and the mutation result is written, the dependencies are unblocked. At that point we _may_ also want to make sure that we don't convert cache-and-network operations that have previously been blocked to cache-first, and instead let them refetch once they're unblocked.

2. Synchronise Optimistic Mutation settling

The solution to the second problem is to treat ongoing mutations that had optimistic updates as a batch. We may have to improve our _detection_ of optimistic writes for this to work, which is also a requirement for #683.

All optimistic updates for mutations are marked. When mutation results for optimistic mutations (previously marked) are returned from the server, they're added to a small queue. These results are only processed as a batch.

Such a batch would first invalidate all optimistic layers, and then apply all updates. This batching causes updates to never see the optimistic updates that have previously been made and hence protects them from being committed to a non-optimistic layer.

high priority 馃挜

Most helpful comment

@frederikhors For sure! I鈥檓 only thinking we may time this to go out either tomorrow or on Monday. We鈥檇 like to make sure it works as it should, as it鈥檚 a major change. Although if everything works correctly it鈥檚 a massive improvement.

I鈥檓 currently looking into whether there鈥檚 anything we need to prepare before we release this, and whether it changes anything for offline support (e.g. makes it trivial to implement right now)

All 4 comments

This is being addressed in #750

Are you going to release this, @kitten?

@frederikhors For sure! I鈥檓 only thinking we may time this to go out either tomorrow or on Monday. We鈥檇 like to make sure it works as it should, as it鈥檚 a major change. Although if everything works correctly it鈥檚 a massive improvement.

I鈥檓 currently looking into whether there鈥檚 anything we need to prepare before we release this, and whether it changes anything for offline support (e.g. makes it trivial to implement right now)

This has been released in @urql/[email protected]

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fillipvt picture fillipvt  路  4Comments

nicollecastrog picture nicollecastrog  路  3Comments

ivosequeros picture ivosequeros  路  5Comments

dotansimha picture dotansimha  路  4Comments

narinluangrath picture narinluangrath  路  3Comments