-
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
Accommodate @client @export
variable changes in ObservableQuery
#4604
Conversation
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.
Let's take this opportunity to consolidate local state logic, rather than just adding another addExportedVariables
call.
When using `client.watchQuery` to setup an Observable against a query that's using `@client @export` directives, cache changes could happen that lead to the value of the `@client @export` variable changing. When this happens, if the watched query is using a mixture of local and remote data, the watched query itself might become invalid, since the `@client @export` variable used to fetch the data has now changed. To address this, this commit updates the `ObservableQuery` observers such that they first check to see if `@client @export` directives are being used, and update any associated variables. It will then perform a `refetch` using the new variables if needed, otherwise it will let the observers continue with their normal behaviour.
7d0cfd0
to
a8f944d
Compare
// changed, and the query is calling against both local and remote | ||
// data, a refetch is needed to pull in new data, using the | ||
// updated `@export` variables. | ||
if (queryManager.transform(query).hasClientExports) { |
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.
By using cached data from queryManager.transform(query)
we can avoid repeatedly calling hasClientExports
or queryManager.getLocalState().serverQuery
(below).
@@ -713,7 +713,7 @@ export class QueryManager<TStore> { | |||
}> | |||
>(); | |||
|
|||
private transform(document: DocumentNode) { | |||
public transform(document: DocumentNode) { |
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.
I don't love making this public, but at least the result type is read-only.
PR #4604 fixed an issue where changes made to `@client @export` based variables didn't always result in re-running the query that was using the variable. Unfortunately, these changes are a bit too aggressive. They're triggering a `refetch` when an `@client @export` based variable changes (and a few additional conditions are met), and while using the `ObservableQuery.refetch()` method does fix the original issue, it leads to a situation where the query being re-run is always fired over the network, even if the updated query could have been resolved from the cache. `ObservableQuery.refetch()` forces queries to use a network based fetch policy, which means if the query was originally fired with a `cache-first` policy (for example), and has matching data in the cache after taking into consideration the new variable, that data won't be used and instead an extra unnecessary network request will fire. This commit addresses the issue by leveraging `ObservableQuery.setVariables()` instead of automatically refetching. `setVariables` will attempt to resolve the updated query from the cache first, then only fire it over the network if required.
PR #4604 fixed an issue where changes made to `@client @export` based variables didn't always result in re-running the query that was using the variable. Unfortunately, these changes are a bit too aggressive. They're triggering a `refetch` when an `@client @export` based variable changes (and a few additional conditions are met), and while using the `ObservableQuery.refetch()` method does fix the original issue, it leads to a situation where the query being re-run is always fired over the network, even if the updated query could have been resolved from the cache. `ObservableQuery.refetch()` forces queries to use a network based fetch policy, which means if the query was originally fired with a `cache-first` policy (for example), and has matching data in the cache after taking into consideration the new variable, that data won't be used and instead an extra unnecessary network request will fire. This commit addresses the issue by leveraging `ObservableQuery.setVariables()` instead of automatically refetching. `setVariables` will attempt to resolve the updated query from the cache first, then only fire it over the network if required.
PR #4604 fixed an issue where changes made to `@client @export` based variables didn't always result in re-running the query that was using the variable. Unfortunately, these changes are a bit too aggressive. They're triggering a `refetch` when an `@client @export` based variable changes (and a few additional conditions are met), and while using the `ObservableQuery.refetch()` method does fix the original issue, it leads to a situation where the query being re-run is always fired over the network, even if the updated query could have been resolved from the cache. `ObservableQuery.refetch()` forces queries to use a network based fetch policy, which means if the query was originally fired with a `cache-first` policy (for example), and has matching data in the cache after taking into consideration the new variable, that data won't be used and instead an extra unnecessary network request will fire. This commit addresses the issue by leveraging `ObservableQuery.setVariables()` instead of automatically refetching. `setVariables` will attempt to resolve the updated query from the cache first, then only fire it over the network if required.
PR #4604 fixed an issue where changes made to `@client @export` based variables didn't always result in re-running the query that was using the variable. Unfortunately, these changes are a bit too aggressive. They're triggering a `refetch` when an `@client @export` based variable changes (and a few additional conditions are met), and while using the `ObservableQuery.refetch()` method does fix the original issue, it leads to a situation where the query being re-run is always fired over the network, even if the updated query could have been resolved from the cache. `ObservableQuery.refetch()` forces queries to use a network based fetch policy, which means if the query was originally fired with a `cache-first` policy (for example), and has matching data in the cache after taking into consideration the new variable, that data won't be used and instead an extra unnecessary network request will fire. This commit addresses the issue by leveraging `ObservableQuery.setVariables()` instead of automatically refetching. `setVariables` will attempt to resolve the updated query from the cache first, then only fire it over the network if required.
PR #4604 fixed an issue where changes made to `@client @export` based variables didn't always result in re-running the query that was using the variable. Unfortunately, these changes are a bit too aggressive. They're triggering a `refetch` when an `@client @export` based variable changes (and a few additional conditions are met), and while using the `ObservableQuery.refetch()` method does fix the original issue, it leads to a situation where the query being re-run is always fired over the network, even if the updated query could have been resolved from the cache. `ObservableQuery.refetch()` forces queries to use a network based fetch policy, which means if the query was originally fired with a `cache-first` policy (for example), and has matching data in the cache after taking into consideration the new variable, that data won't be used and instead an extra unnecessary network request will fire. This commit addresses the issue by leveraging `ObservableQuery.setVariables()` instead of automatically refetching. `setVariables` will attempt to resolve the updated query from the cache first, then only fire it over the network if required.
When using
client.watchQuery
to setup anObservable
against a query that's using@client @export
directives, cache changes could happen that lead to the value of the@client @export
variable changing. When this happens, if the watched query is using a mixture of local and remote data, the watched query itself might become invalid, since the@client @export
variable used to fetch the original data has now changed.To address this, this PR updates the
ObservableQuery
observers such that they first check to see if@client @export
directives are being used, and update any associated variables.ObservableQuery
will then perform arefetch
using the new variables if needed, otherwise it will let the observers continue with their normal behaviour.It's important to note that these changes introduce Promises into
ObservableQuery
subscription handling, which can impact the timing ofObservableQuery
subscriber object calls and/or callbacks. I haven't yet determined how much of an impact this could have in practice, but these changes did impact one existing test suite. I've modified the tests to accommodate these changes (as I believe that test did not represent a real usage scenario), but I think we'll need to consider the impact of these changes carefully before merging.Fixes #4530.