Skip to content
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

pause stream vs cancel stream #114

Closed
sc00n opened this issue Oct 29, 2020 · 4 comments
Closed

pause stream vs cancel stream #114

sc00n opened this issue Oct 29, 2020 · 4 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@sc00n
Copy link
Contributor

sc00n commented Oct 29, 2020

When I use the accelerometer in the mobile sensing package, and I use a frequency of 20 vs 10:

 study.addTriggerTask(
      ImmediateTrigger(),
      AutomaticTask(name: 'Sensor Task')
        ..addMeasure(PeriodicMeasure(MeasureType(NameSpace.CARP, SensorSamplingPackage.ACCELEROMETER),
            frequency: const Duration(seconds: 10), duration: const Duration(milliseconds: 100)));

vs

study.addTriggerTask(
      ImmediateTrigger(),
      AutomaticTask(name: 'Sensor Task')
        ..addMeasure(PeriodicMeasure(MeasureType(NameSpace.CARP, SensorSamplingPackage.ACCELEROMETER),
            frequency: const Duration(seconds: 20), duration: const Duration(milliseconds: 100)));

I get, in the end, the same amount of measurements (on my Iphone XS iOS 13.4.1 , the first writes 1000 every 10 seconds, the second writes 2000 every 20 seconds). This is because the stream is paused during the 10 (or 20) seconds. When the stream is resumed, everything that was in the stream is written in the json file. So in the background, the phone is still sampling constantly, and outputting the result to the stream.

First of all, this leads to a massive amount of data, and an explosion of the json file. Second, I guess (I am not sure though), this also drains battery faster.

In the flutter documentation you can read in the pause documentation:

To avoid buffering events on a broadcast stream, it is better to cancel this subscription, and start to listen again when events are needed, if the intermediate events are not important.

Also, maybe related, in the creating streams documentation, you can find:

Honoring the pause state
Avoid producing events when the listener has requested a pause. An async* function automatically pauses at a yield statement while the stream subscription is paused. A StreamController, on the other hand, buffers events during the pause. If the code providing the events doesn’t respect the pause, the size of the buffer can grow indefinitely. Also, if the listener stops listening soon after pausing, then the work spent creating the buffer is wasted.

`

@sc00n
Copy link
Contributor Author

sc00n commented Oct 30, 2020

When I change onResume from BufferingPeriodicStreamProbe , only the measurements during the duration, no matter the frequency, are saved and written down. I cancel the stream and reopen it again according to the frequency (instead of pausing):

abstract class BufferingPeriodicStreamProbe extends PeriodicStreamProbe {

...

  Future<void> onResume() async {
    // if we don't have a subscription yet, or it has been canceled, try to get one
    subscription ??= bufferingStream?.listen(onSamplingData, onError: onError, onDone: onDone);

    subscription?.resume();
    timer = Timer.periodic(frequency, (Timer t) {
    subscription = bufferingStream?.listen(onSamplingData, onError: onError, onDone: onDone);
      onSamplingStart();
      Timer(duration, () {
      subscription?.cancel();

        onSamplingEnd();
        getDatum().then((datum) {
          if (datum != null) controller.add(datum);
        }).catchError((error, stacktrace) => controller.addError(error, stacktrace));
      });
    });
  }

...


}

This seems to work fine on my Android.

If you think this is a good idea, I can also make an optional bool in PeriodicMeasure where you can choose to cancel/pause?

I might however be missing the point of pausing instead of cancelling :). There might be other reasons to pause instead of cancel the stream of which I am not aware.

@bardram
Copy link
Contributor

bardram commented Nov 24, 2020

I think you're right. The idea is that data sampling should not happen when the probe is paused. Hence, it seems like canceling (rather than pausing) is the correct way. I will look into changing this. But need to make sure that there are no side-effect.

Making the optional bool don't seems to be a good idea, though. This would be difficult for the app developer to know which to choose.

@bardram bardram self-assigned this Nov 24, 2020
@bardram bardram added bug Something isn't working enhancement New feature or request labels Nov 24, 2020
@bardram
Copy link
Contributor

bardram commented Nov 25, 2020

Looked into this, and you're absolutely right -- it keeps buffering event even when paused. This is now fixed as part of version 0.10.0 which will be released as soon as it as been tested and documented.

bardram added a commit that referenced this issue Nov 25, 2020
@bardram
Copy link
Contributor

bardram commented Nov 30, 2020

Version 0.10.0 now released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants