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

skipUntil and time-framed Producers #2575

Closed
cesteban opened this issue Nov 28, 2015 · 2 comments
Closed

skipUntil and time-framed Producers #2575

cesteban opened this issue Nov 28, 2015 · 2 comments
Labels

Comments

@cesteban
Copy link
Contributor

I'm struggling to get this right. I have a SignalProducer that will send Quality of Service prediction values every 20 milliseconds. My requirements are:

  • Discard all the values sent during the first filteringTime seconds of every experiment.
  • Throttle the output to throttlingTime seconds.
  • Restart the signal producer every experimentDuration seconds.
  • Perform maxExperiments restarts, then complete.

This is my best approach for the moment:

func qualityOfServiceSignalProducer(filteringTime filteringTime: NSTimeInterval, throttlingTime: NSTimeInterval, maxExperiments: Int, experimentDuration: NSTimeInterval) -> SignalProducer<QualityLevel, NoError>
{
    let filterTimerProducer = SignalProducer<(), NoError> { sink, disposable in
        self.scheduler.scheduleAfter(self.scheduler.currentDate.dateByAddingTimeInterval(filteringTime)) {
            sink.sendCompleted()
        }
    }

    let endExperimentTimerProducer = SignalProducer<(), NoError> { sink, disposable in
        self.scheduler.scheduleAfter(self.scheduler.currentDate.dateByAddingTimeInterval(experimentDuration)) {
            sink.sendCompleted()
        }
    }

    return self.tesseractReactiveMonitor.forecastSignalProducer() //the signal producer that sends QoS predictions on start
        .skipUntil(filterTimerProducer)
        .throttle(throttlingTime, onScheduler: scheduler)
        .takeUntil(endExperimentTimerProducer)
        .times(maxExperiments)
}

What bothers me the most is to have to use these two timers, filterTimerProducer and endExperimentTimerProducer, in combination with takeUntil-like operators, which feels a little bit artificial. I wonder if there is a better approach using existing RAC operators.

My other concern is that RAC doesn't provide a skipUntil operator. Given the symmetry between:

  • take ~> skip
  • takeWhile ~> skipWhile

I was expecting to also have takeUntil ~> skipUntil. Perhaps I'm missing something and there is a better way to implement this skipUntil behavior with existing operators?

Anyway, I've created a skipUntil implementation by pretty much mimicking takeUntil in this commit: cesteban@fbf467c

I will send a pull request if you think this could be useful for anybody else. It is definitely useful for me unless anybody can suggest a better approach.

Thanks a lot. Any advice will be greatly appreciated.

@mdiep mdiep added the question label Nov 28, 2015
@NachoSoto
Copy link
Member

I was expecting to also have takeUntil ~> skipUntil. Perhaps I'm missing something and there is a better way to implement this skipUntil behavior with existing operators?

I will send a pull request if you think this could be useful for anybody else. It is definitely useful for me unless anybody can suggest a better approach

I agree, I think skipUntil can be considered a fundamental operator and therefore we should have it.

I took a quick look at your implementation and except for a couple of small things I think it looks great!

@cesteban
Copy link
Contributor Author

Great, I'm making the requested changes and sending the PR.

Thanks @NachoSoto!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants