2

Please look at the following pseudo code using Dart Riverpod.

final dependingStreamProvider = StreamProvider.autoDispose<int>((ref) {
  final depending = ref.watch(dependingProvider);

  if (depending == typeA) {
     return AStream(); // returns stream of int
  } else {
     return BStream(); // returns a different stream of int
  }
});

In this case, as dependingProvider changes its status, the StreamProvider creates another Stream instance.

My question is, does the stale Stream instance gets disposed of (i.e., its StreamController gets closed) by Riverpod? Or do we have to handle ourselves somehow?

I saw a similar question here: Do you have to manually dispose streams from a streamprovider in Flutter? but I wasn't quite sure if the accepted answer refers to my case above.

I understand that autoDispose will take care of the disposal when there is nobody listening to the StreamProvider itself, but the above case is a different case

barley
  • 4,403
  • 25
  • 28

1 Answers1

1

I went ahead and created a sample code.

TL;DR Yes, the StreamProvider disposes of the previous Stream instance and its subscription.


I created the following Providers, so that streamProvider switches between streamA and streamB based on the state of switcherProvider.

final streamProvider = StreamProvider<int>((ref) {
  final switcher = ref.watch(switcherProvider);

  if (switcher == StreamType.A) {
    return streamA;
  } else {
    return streamB;
  }
});

final streamA = Stream.periodic(const Duration(seconds: 1), (x) {
  print("Emitting $x from stream A");
  return x;
});

final streamB = Stream.periodic(const Duration(seconds: 1), (x) {
  print("Emitting $x from stream B");
  return x;
});

enum StreamType { A, B }

class StreamTypeNotifier extends StateNotifier<StreamType> {
  StreamTypeNotifier() : super(StreamType.A);

  void switchStream() {
    state = state == StreamType.A ? StreamType.B : StreamType.A;
  }
}

final switcherProvider =
    StateNotifierProvider<StreamTypeNotifier, StreamType>((ref) {
  return StreamTypeNotifier();
});

On tapping FAB, it switches the state of switcherProvider.

 void _toggleSwitcher() {
    ref.read(switcherProvider.notifier).switchStream();
    ...
 }

...

  @override
  Widget build(BuildContext context) {
    ref.watch(streamProvider);
    ...
  }

The result is this:

enter image description here

As I tap the FAB for the first time and switch to streamB, streamA does not emit a new value. As I tap the FAB for the second time and switch to streamA, no stream emits any value, since both of the streams are automatically closed.

barley
  • 4,403
  • 25
  • 28