-
-
Notifications
You must be signed in to change notification settings - Fork 932
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
On rebuild, don't clear dependencies until the new future of a futureProvider completes #1253
Comments
The issue is that some futures can take a very long time before they complete. With version 2.0, there are a few features related to autoDispose that could help. Namely cacheTime and disposeDelay I'm considering setting disposeDelay to 5 seconds by default. So unless yourFutureProvider takes more than 5 seconds, its dependencies wouldn't be disposed. |
Personally I feel that over-retaining rather than under-retaining is better, and it matches my mental model of what I expect. I think my mental model is similar to a garbage collector, where any reference to another provider retains it. And this surprised me because there's no other obvious way of retaining another provider. It feels like maybe we're almost getting in to weak and strong references? Whilst there definitely are futures that take a long time to complete, I don't feel they're that common in app state management, and I can't think of a time where I've had one.
These looks really useful, thanks
I feel that could a bad idea and lead to even more surprising and confusing behaviour. For example I could see a situation where a HTTP endpoint normally returns quickly, but one day the server is slow and it takes 7 seconds... and you end up with a provider that never loads, because some state keeps being disposed. I image that'd be pretty hard to debug. |
A bigger problem is that I don't want "watch" to behave differently based on the provider And it's not exactly clear how this could be generalized to others. |
Why would it never load? If a provider is disposed + recreated because the request was too slow, that shouldn't trigger side effects |
FutureProvider
@rrousselGit I can't remember exactly what I was thinking of, but could you end up in a hard-to-understand situation like this? // If this disposes by default after 5 seconds...
final localStateProvider = StateProvider.autoDispose(...);
final homePageDataProvider = FutureProvider.autoDispose<String>(
(ref) async {
// ...then if this endpoint is refreshed, and takes longer than 5 seconds,
// the local state is disposed?
//
// But less than 5 seconds and app state is re-watched so it doesn't get disposed?
final endpointData = await ref.watch(endpointProvider.future);
final localState = ref.watch(localStateProvider);
...
},
); So your app works fine... until one day the server is slow and local state starts resetting? |
Yes, that could happen. I'm thinking about doing: "When rebuilding a provider, keep dependencies until value other than AsyncLoading is emitted". |
@rrousselGit just to give you some real-world context, this is what we're doing in a production app... final endpointProvider = StateNotifierProvider.autoDispose<
EndpointNotifier<String>, AsyncValue<String>>((ref) {
// Manages fetching data from a HTTP endpoint
});
final futureProvider = FutureProvider.autoDispose((ref) async {
final shouldDoRequest = await ref.watch(someConditionProvider.future);
if (shouldDoRequest) {
return await ref.watch(endpointProvider.future);
}
return null;
}); We have separate providers for every endpoint (and it's working fantastically, hoping to do many blog posts about this!). Ideally, if Some of the endpoint data is quite large, so we want to dispose it the second nothing is listening to it anymore. Would "keep dependencies until value other than AsyncLoading is emitted" achieve that, even if |
Yes. |
It would be great to have this issue resolved from my point of view.
Is there anything else that needs to be taken into account? |
I love that you want to contribute. But I won't lie: It's at the very top of my todo-list. I was about to do it this week, if not today. It's probably not worth that you look into it. |
That actually sounds even better! Happy to then test it when you're done. |
I guess I ended up taking a break 🤷 |
Just ran into this after one of my providers started firing off hundreds of requests because I was |
Hello, I was wondering if there could there be a way of
FutureProvider
keeping watched dependent providers alive until the next value is generated?I found the behaviour of this simple app very surprising:
I’m aware that moving
ref.watch(counter)
above theawait
will fix this issue, as would directly listening tocounter
from the widget tree, but neither are ideal in my situation.This case seems seems especially counterintuitive as it was
counter
that trigger the rebuild.Would it be possible to have a behaviour that defers unsubscribing from providers until after the next value has been generated? So it would go...
I feel for me this would be a more obvious default (but I’m fairly sure it’ll cause other problems I haven’t thought of 😀). This seems to have come up in various issues before, but as far as I can see there isn’t an easy solution right now.
Thanks for the great work, as always!
The text was updated successfully, but these errors were encountered: