-
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
Make updating cache.makeVar variables broadcast watches. #5976
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This essentially undoes #5484, so that reactive variables (which have access to the InMemoryCache object but know nothing about proxy objects) can benefit from transactional broadcast batching when calling cache.broadcastWatches().
Shorter, and not as suggestive of Apollo Client 2.x local state. Returns a function of type ReactiveVar<T> (f.k.a. LocalVar<T>). Follow-up to #5799.
The broadcast is always synchronous, but you can group multiple variable updates together (with just one broadcast) using cache.performTransaction.
hwillson
approved these changes
Feb 21, 2020
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great @benjamn! 🎉
benjamn
added a commit
that referenced
this pull request
Jun 30, 2020
The makeVar method was originally attached to InMemoryCache so that we could call cache.broadcastWatches() whenever the variable was updated. See #5799 and #5976 for background. However, as a number of developers have reported, requiring access to an InMemoryCache to create a ReactiveVar can be awkward, since the code that calls makeVar may not be colocated with the code that creates the cache, and it is often desirable to create and initialize reactive variables before the cache has been created. As this commit shows, the ReactiveVar function can infer the current InMemoryCache from a contextual Slot, when called without arguments (that is, when reading the variable). When the variable is updated (by passing a new value to the ReactiveVar function), any caches that previously read the variable will be notified of the update. Since this logic happens at variable access time rather than variable creation time, makeVar can be a free-floating global function, importable directly from @apollo/client. This new system allows the variable to become associated with any number of InMemoryCache instances, whereas previously a given variable was only ever associated with one InMemoryCache. Note: when I say "any number" I very much mean to include zero, since a ReactiveVar that has not been associated with any caches yet can still be used as a container, and will not trigger any broadcasts when updated. The Slot class that makes this all work may seem like magic, but we have been using it ever since Apollo Client 2.5 (#3394, via the optimism library), so it has been amply battle-tested. This magic works.
Just a quick note that we've made this API even easier to use ( |
benjamn
added a commit
that referenced
this pull request
Jun 30, 2020
…6512) The makeVar method was originally attached to InMemoryCache so that we could call cache.broadcastWatches() whenever the variable was updated. See #5799 and #5976 for background. However, as a number of developers have reported, requiring access to an InMemoryCache to create a ReactiveVar can be awkward, since the code that calls makeVar may not be colocated with the code that creates the cache, and it is often desirable to create and initialize reactive variables before the cache has been created. As this commit shows, the ReactiveVar function can infer the current InMemoryCache from a contextual Slot, when called without arguments (that is, when reading the variable). When the variable is updated (by passing a new value to the ReactiveVar function), any caches that previously read the variable will be notified of the update. Since this logic happens at variable access time rather than variable creation time, makeVar can be a free-floating global function, importable directly from @apollo/client. This new system allows the variable to become associated with any number of InMemoryCache instances, whereas previously a given variable was only ever associated with one InMemoryCache. Note: when I say "any number" I very much mean to include zero, since a ReactiveVar that has not been associated with any caches yet can still be used as a container, and will not trigger any broadcasts when updated. The Slot class that makes this all work may seem like magic, but we have been using it ever since Apollo Client 2.5 (#3394, via the optimism library), so it has been amply battle-tested. This magic works.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR makes two user-visible changes:
cache.makeLocalVar
API introduced in Implement reactive variables for tracking local state. #5799 has been renamed tocache.makeVar
, for brevity and to avoid direct association with Apollo Client 2.x local state. Reactive variables should replace most use cases for local state, but they have many other potential uses. The type of the returned variable is nowReactiveVar<T>
instead ofLocalVar<T>
.cache.broadcastWatches()
. Because theApolloCache
API is mostly synchronous, this broadcast is also synchronous, but it's possible to batch multiple variable updates together by performing them within acache.performTransaction
block.These changes are vital for making reactive variables truly reactive, but we still have some work to do to make sure broadcasting watched query data from the cache reliably pushes the new data into the view layer.