I have a RxJava2 Flowable chain which includes some heavy computation. I want to make sure that the whole chain is only called one per request and that there is at most one active request at any given time.
Here's an example timeline:
-R-------R--R-R----R-------
--C....E--C....E----C....E-
In the above, - is idle time, R are input requests and C are computations that happen (starting with C, processing denoted by . and computation end denoted by E).
As you can see:
This is what I got so far:
System.out.println("start");
CountDownLatch countDownLatch = new CountDownLatch(1);
AtomicBoolean valve = new AtomicBoolean(true);
Flowable.interval(100, TimeUnit.MILLISECONDS)
.take(30)
.filter(e -> valve.get())
.observeOn(Schedulers.computation())
.map(e -> {
valve.set(false);
System.out.println("map " + e);
Thread.sleep(550);
return e;
})
.observeOn(Schedulers.single())
.subscribe(
e -> {
System.out.println("subscribe " + e);
valve.set(true);
},
e -> {
System.out.println("error " + e);
valve.set(true);
},
() -> {
System.out.println("complete");
valve.set(true);
countDownLatch.countDown();
});
countDownLatch.await();
System.out.println("end");
So I have the flow that:
This seems to be working fine, but I was wondering whether there's a RxJava2-only solution that could be put instead of making use the outside of AtomicBoolean. I'm looking for that for two reasons:
Note CountDownLatch
above is just for testing - I'm running this from my main
method, and because there's an observeOn
, the flow is executed on another thread, so main
finishes before the flow executes. In real app, this won't be the case.
The real use case is an app which has a button which triggers some calculation that takes a few seconds. I don't want this to be triggered multiple times if the user clicks multiple times while the previous calculation is still in progress.
I'm fine with changing the flow if there are better solutions to this particular use case in RxJava.