Code Monkey home page Code Monkey logo

Comments (9)

rrousselGit avatar rrousselGit commented on May 24, 2024 1

In any case, the pausing mechanism is receiving a big overhaul in 3.0. So that docs page will likely receive a lot of change for 3.0 :)

from riverpod.

rrousselGit avatar rrousselGit commented on May 24, 2024 1

, but aren't we unable to resume a StreamSubscription that has already been canceled?

No we can. There's "StreamSubscription.resume" and the controller.onResume lifecycle

And "dispose" would be more like controller.onDone

from riverpod.

rrousselGit avatar rrousselGit commented on May 24, 2024

I think you're confused about what "the provider is paused" means.
It's about how ref.watch will not cause the provider to rebuild.

For instance consider:

final provider = Provider((ref) {
   print('rebuild');
  Timer(Duration(seconds: 2), () => ref.invalidateSelf());
});

This provider will print rebuild every 2 seconds if it is not paused.

Yet you'll notice that if you do a simple ref.read(provider) and never ref.listen/ref.watch it anywhere, only a single rebuild will be logged.

from riverpod.

rrousselGit avatar rrousselGit commented on May 24, 2024

In your snippet, the provider is correctly paused. This can be checked with ref.onResume/ref.onCancel:

class DetailsNotifier extends Notifier<int> {
  @override
  int build() {
    print('start');
    ref.onResume(() {
      print('resume');
    });
    ref.onCancel(() {
      print('pause');
    });
   ...
  }
}

You'll see that when popping the detail page, pause is called. And reopening it calls resume.

Your specific issue is: ref.listen subscriptions are not cancelled when a provider is paused. So the listener is still invoked, even though the provider is paused.
This is voluntary, as paused providers likely want to keep performing work in some cases.

The solution in your case is to manually cancel the subscription:

ProviderSubscription? sub = ref.listen(appNotipod, (previous, next) {
  print('Listen appNotipod  ${DateTime.now()}');
});

// Stop listening on pause
ref.onCancel(() => sub?.cancel());

// Restart the listening on resume
ref.onResume(() => sub = ref.listen(appNotipod, (previous, next) {
  print('Listen appNotipod  ${DateTime.now()}');
})); 

v3 will make this more straightforward as you'll be able to do:

final sub = ref.listen(appNotipod, (previous, next) {
  print('Listen appNotipod  ${DateTime.now()}');
});

ref.onCancel(sub.pause);

// Restart the listening on resume
ref.onResume(sub.resume); 

from riverpod.

rrousselGit avatar rrousselGit commented on May 24, 2024

We could consider making a breaking change for 3.0, and have ref.listen pause by default when a provider is paused.
With maybe an optional flag on ref.listen to opt out:

ref.listen(p, maintainSubscriptionOnCancel: true, ...);

from riverpod.

eli1stark avatar eli1stark commented on May 24, 2024

I see, so the pausing relates more to the body of the provider. If it just returns a complex object like ProfileService or ProfileNotifier that has its inner subscriptions, they will continue to work.

I would suggest maybe renaming onCancel to onPaused. While I understood what onResume did at first glance, I couldn't guess the purpose of onCancel until I tried it. This naming will mimic lifecycle of the widgets.

Thank you for the clarification!

from riverpod.

eli1stark avatar eli1stark commented on May 24, 2024

We could consider making a breaking change for 3.0, and have ref.listen pause by default when a provider is paused. With maybe an optional flag on ref.listen to opt out:

ref.listen(p, maintainSubscriptionOnCancel: true, ...);

This would be an interesting concept and would offer more control over background services held by providers.

from riverpod.

rrousselGit avatar rrousselGit commented on May 24, 2024

I would suggest maybe renaming onCancel to onPaused.

I named it onCancel because that's the official name in Dart. Cf StreamController.onCancel

from riverpod.

eli1stark avatar eli1stark commented on May 24, 2024

I would suggest maybe renaming onCancel to onPaused.

I named it onCancel because that's the official name in Dart. Cf StreamController.onCancel

It makes sense, but aren't we unable to resume a StreamSubscription that has already been canceled? This is where the confusion arises because 'cancel' is more associated with 'dispose' for me, while 'pause' suggests that it's still here and can be resumed later. Similar to StreamSubscription, we can pause them and resume later, but once canceled, it's done.

from riverpod.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.