11

I'm using RxJava. I have to execute a specific task every 5 seconds. That works perfectly by using the "Observable.Interval" method. However, I also have the following constraint: A new task must not be executed if the last task didn't finished. In this case, the new task need to be executed only when the last one finished.

I can't figure out how to do this simply with RxJava.

All ideas would be really appreciated ^^

Thanks for reading.

ayorosmage
  • 1,607
  • 1
  • 15
  • 21

2 Answers2

15

When you call interval a worker is selected that corresponds to a single thread from the given scheduler (default is computation):

Observable
    .interval(5, TimeUnit.SECONDS)
    .flatMap(n -> task());

or if nothing is returned by the task:

Observable
   .interval(5, TimeUnit.SECONDS)
   .doOnNext(n -> task());

This means that for every 5 seconds there will be a run but if the task takes 5 or more seconds then the tasks will be running continuously (but not concurrently).

If you want to ensure a gap between running tasks then you could skip tasks based on the time of the finish of the last task. I can flesh that out if you need it.

Dave Moten
  • 11,957
  • 2
  • 40
  • 47
  • Thanks a lot for your answer. Indeed, I need to ensure the gap between the running tasks. Ideally I was searching for a pure "reactivex" solution to this problem. However, maybe in practice adding specific code to skip the task based on a timestamp as you advice is the simplest way to go... – ayorosmage Dec 11 '16 at 14:16
  • If I change the interval, will the observable automatically change or is it constant? How can I have the interval dynamically controlled by a different setter? – Shimmy Weitzhandler Jun 10 '19 at 01:28
4

Small fix to Dave Moten's answer: if need it to actually work - you should NOT forget to subscribe. You should do

   Observable
    .interval(5, TimeUnit.SECONDS)
    .doOnNext(n -> task())
    .subscribe()
Tauri
  • 1,291
  • 1
  • 14
  • 28