evgeniy44
evgeniy44

Reputation: 3162

RxJava check condition with delay

Let's say I need to request a report from remote service. According to its API I need to do it in 3 steps: 1. Submit a request for report collecting(as a response I get reportId). 2. Check report status until it becomes 'done' with some delay(e.g. 10 seconds). 3. And finally get the report by id.

So, the question is following: is there any way using RxJava API check a predicate function until it returns true with some delay?

The most appropriate operator I could find was 'takeUntil' and code was something like this:

Observable.just(request)
            .map(this::submitAndGetId)
            .takeUntil(this::reportIsDone)
            .map(this::getReport)

But I couldn't find a way to specify the delay between status checks

Upvotes: 1

Views: 1392

Answers (1)

Dave Moten
Dave Moten

Reputation: 12087

Use flatMap and interval:

Observable
  .just(request)
  .map(this::submitAndGetId)
  .flatMap(id -> 
    Observable
        .interval(1, TimeUnit.SECONDS)
        .filter(n -> reportIsDone(id))
        .map(n -> id)
        .first()
  )
  .map(this::getReport);

For a capped exponential backoff on the retries:

Observable<Long> retries = 
  Observable
    .just(1, 2, 4, 8, 16)
    .concatWith(Observable.just(30).repeat())
    .flatMap(n -> Observable.timer(n, TimeUnit.SECONDS));

Observable
  .just(request)
  .map(this::submitAndGetId)
  .flatMap(id -> 
     retries
        .filter(n -> reportIsDone(id))
        .map(n -> id)
        .first()
  )
  .map(this::getReport);

Upvotes: 3

Related Questions