nurkiewicz/async-retry

RetryOn ignored due to wrong command order

dennisfischer opened this issue · 4 comments

Hey Tomasz,

Throwing a "UploadResponseException with status code 503":
The abortIf predicate will return false
Tested in java7 backport.

Example order 1 (failing):

        final RetryExecutor executor = new AsyncRetryExecutor(schedueler).withExponentialBackoff(5000, 2)
                .withMaxDelay(30000)
                .withMaxRetries(2)
                .retryOn(IOException.class)
                .retryOn(RuntimeException.class)
                .abortIf(new Predicate<Throwable>() {
                    @Override
                    public boolean apply(@Nullable final Throwable input) {
                        boolean instance = input instanceof UploadResponseException;
                        System.out.println("Instance: " + instance);
                        if (instance) {
                            boolean test = SC_500 >= ((UploadResponseException) input).getStatus();
                            System.out.println("Test: " + test);
                            return test;
                        }
                        return false;
                    }
                })
                .retryOn(UploadResponseException.class)
                .abortOn(MetaBadRequestException.class)
                .abortOn(FileNotFoundException.class)
                .abortOn(UploadFinishedException.class);

Example order 2 (working):

final RetryExecutor executor = new AsyncRetryExecutor(schedueler).withExponentialBackoff(5000, 2)
                .withMaxDelay(30000)
                .withMaxRetries(2)
                .retryOn(IOException.class)
                .retryOn(RuntimeException.class)
                .retryOn(UploadResponseException.class)
                .abortIf(new Predicate<Throwable>() {
                    @Override
                    public boolean apply(@Nullable final Throwable input) {
                        boolean instance = input instanceof UploadResponseException;
                        System.out.println("Instance: " + instance);
                        if (instance) {
                            boolean test = SC_500 >= ((UploadResponseException) input).getStatus();
                            System.out.println("Test: " + test);
                            return test;
                        }
                        return false;
                    }
                })
                .abortOn(FileNotFoundException.class)
                .abortOn(UploadFinishedException.class);

Seems like my retryOn is ignored if using the wrong order.
It'd be nice to have compile time check for correct order (like typeof) or to fix this bug.

Yes, the library is vulnerable to the order of abort/retry calls, unfortunately. Thank you for such complex examples, I'll make unit tests out of them and try to sort out how this can be improved. In general the order shouldn't matter, at all.

I think both examples can be reduced to the "abortIf" and "retryOn(UploadResponseException.class)" lines.
(+ on retryOn line probably)?

Sorry for the delay, it's fixed and released under version 0.0.3. Unfortunately I haven't had time to back port changes to Java 7 but as far as I understand workaround exists. Thanks for reporting!

That's right. The "workaround" is putting the statements in another order.