0
votes

I am trying to set up an exponential back off via an Observable.timer if the network is down or if a given service is down. I have a retryWhen when there are errors.

I have two issue, I cannot get the timer to work, no matter the time set, it always runs immediately. From what I know in the docs it should run the delay then send a complete, but when I look at the logs, I see no delay.

Second is because of I wanted to get the value of the retry when it is returned I used subscribe to get it, however when Observable error is returned it throws an exception when I do the calculations. For the second issue, I plan to do a check on the type of Observable and action it depending on the type.

If I could get ideas on what I may be doing wrong that would be great

return Observable.zip(
    locationObservable,
    oAdapterService.getIssuerInformation(sponsorCode),
    oAdapterService.getOfferInformation(sponsorCode, activity.getOfferCode()),
    (LocationInfo a, IssuerInfo b, OfferInfo c) -> {
      OAdapterUtil.setLocationInfo(activity, a);
      OAdapterUtil.setIssuerInfo(activity, b);
      OAdapterUtil.setOfferInfo(activity, c);
      return activity;
    })
    .retryWhen(errors -> errors.zipWith(Observable.range(1, maxRetries), (error, retries) -> {
          if (retries++ < maxRetries) {
            log.debug("Issues with Service call for transaction ID {} with initiator ID {}, retry count {}"
                ,activity.getTransactionId(),activity.getInitiatorId() ,retries);
            return Observable.just(retries);
          }
          log.error("Tried to call Service {} time(s) for for transaction ID {} with initiator ID {}, error is {} "
              ,maxRetries,activity.getTransactionId(),activity.getInitiatorId(),error);
          return Observable.error(error);
        }
    ).flatMap(x -> {

          log.debug("X value in flat map is  {}",x.toString());
          x.subscribe(currentValue -> {
            log.debug("X value in subscribe is with subscribe {}",currentValue.toString());
            double retryCount =  Double.parseDouble(currentValue.toString()) + 2.0  ;
            log.debug("retry count {}",retryCount);
             long exponentialBackOff =(long)Math.pow(2.0, retryCount);
            log.debug("exp back off {}",exponentialBackOff);
        // Observable.timer(exponentialBackOff, TimeUnit.SECONDS);
          });

          Observable.timer(10, TimeUnit.SECONDS);

          return x;
        // Observable.timer(backoffPeriod, TimeUnit.MILLISECONDS);
        }
    ));
1

1 Answers

0
votes

You have an orphan line of code:

      Observable.timer(10, TimeUnit.SECONDS);

The only thing this line of code does is to create an observable. The result is discarded because nothing is done with it.

If you need to back off, then do:

return x.delay(10, TimeUnit.SECONDS);

inside of the flatMap() operator. Remove the x.subscriber(); any logging should be done before returning.