0

I need to run 2 JOB at a specific interval of 4,8,12,16... second and another one is 5,9,13,17...second.

I have used Interval operator in RxJava. Job B needs to run after Job A. Job B should sleep when Job A is running and vice versa. Till now the code looks below

var compositeDisposable = CompositeDisposable()
compositeDisposable.add(Observable.interval(0, recordIntervalPeriod, TimeUnit.MILLISECONDS)
                        .serialize()
                        .subscribe {
                            JobA()
                        })
compositeDisposable.add(Observable.interval(0, recorderStopIntervalStartTime, TimeUnit.MILLISECONDS)
                        .serialize()
                        .subscribe {
                            JobB()
                        })

Need help in following

1. Best way to achieve the above using RxJava

2. Run JobA for 4 second then run JobB for 4 second and repeat the process again.

Chiradeep
  • 973
  • 12
  • 32
  • Some of these requirements are a bit oncpomatible I think 1. "I need to run 2 JOB at a specific interval of 4,8,12,16... second and another one is 5,9,13,17...second." 2. "Job B should sleep when Job A is running and vice versa" 3 "Run JobA for 4 second then run JobB for 4 second and repeat the process again." If both jobs take 4 seconds, and they have to sleep while the other is running, then they can\t be working at the intervals you defined to start with – GSala Mar 22 '20 at 22:38
  • Let me clarify a little bit. Let's say we have an async task and we call another async task from onPostexecute. After the second async task completes its operations it calls the first async task once more and the cycle continues – Chiradeep Mar 22 '20 at 22:45

2 Answers2

1

I would suggest you use a single job that runs every second, and decide each time which job to call based on the counter value:

val disposable = Observable.interval(1, TimeUnit.SECONDS)
        .serialize()
        .subscribe { counter ->
            if (counter % 4 == 0L) {
                jobA()
            } else if ((counter - 1) % 4 == 0L) {
                jobB()
            }
        }

If you still want to use two observables, I think this will work too:

val disposable = CompositeDisposable()
disposable.addAll(
        Observable.interval(4, TimeUnit.SECONDS)
                .subscribe {
                    jobA()
                },
        Observable.interval(4, TimeUnit.SECONDS)
                .delay(1, TimeUnit.SECONDS)
                .subscribe {
                    jobB()
                })

Disclaimer: I haven't used RxJava a lot.

Nicolas
  • 6,611
  • 3
  • 29
  • 73
  • Thanks Nicolas for your answer. This would work. I will still wait for any better approach apart from this :) – Chiradeep Mar 22 '20 at 21:11
  • The problem of the above answer is JobA will run at 4,8,12,16... and JobB will run at 5,9,13... But JobB is not dependent on JobA. Both will run concurrently. – Chiradeep Mar 22 '20 at 21:21
  • The effect should be the same. Unless jobA can take more than 1 second, in which case you want to skip jobB? – Nicolas Mar 22 '20 at 21:25
  • Yes. Kind of. I need to make this synchronised. meaning, JobB should start after JobA but each thread lifecycle should be 4 second strict. – Chiradeep Mar 22 '20 at 21:26
  • So JobA is cancelled when JobB starts and vice versa? JobA max duration is 1 second and JobB is 3 seconds? – Nicolas Mar 22 '20 at 21:35
  • Correct. JobA will always run 4 second and JobB will run 4 second but one after another. Both the job will take 4 second strict. – Chiradeep Mar 22 '20 at 21:37
0

What about

Observable.interval(4,TimeUnit.SECONDS)
    .flatMap({
        jobA().zipWith(Observable.timer(1, TimeUnit.SECONDS) }
            .flatMap { jobB() }
    }, maxConcurrent = 1).subscribe()

I'm assuming jobA() and jobB() are observables of some sort.

Job A should wait on Job B being done, because of the max concurrency set to 1.

Job B should wait on Job A or 1 second from the start of Job A, whichever happens latest.

GSala
  • 946
  • 7
  • 15
  • Thanks for your answer. Both jobA and jobB will not be emitting any data but will be doing some operation in a function block. But idea is to make it synchronised operation. JobA will take 4 second to finish after that jobB will start and also it will take 4 second. Again jobA should start and the iteration will continue.... – Chiradeep Mar 22 '20 at 22:40