guava-retrying icon indicating copy to clipboard operation
guava-retrying copied to clipboard

Is there any way I can mark a tasks that "succeeded only after a retry" ?

Open elad2109 opened this issue 9 years ago • 9 comments

I want to use a backoff retry mechanism to send a list of http requests.

Is there any way I can mark (with flag) the requests that succeeded only after re-try?

elad2109 avatar Feb 25 '16 17:02 elad2109

You might be able to keep track of that in a RetryListener which you give to the RetryerBuilder. Does that solve your issue?

JensRantil avatar Feb 26 '16 11:02 JensRantil

can you help with a code snipet? I'm not sure the code that calls the backoff mechanism can read the falg indicating a request was successful only after a retry?

elad2109 avatar Feb 26 '16 11:02 elad2109

Let's take a step back. What is your use-case? Why do you want to flag the retry?

JensRantil avatar Feb 26 '16 12:02 JensRantil

I have a list of requests. I want to flag each response with "succeeded"(status 200) , "failed", "succeeded after retry"

elad2109 avatar Feb 26 '16 14:02 elad2109

Something like this should probably get you started:

class RetryableRequest implements RetryListener<Boolean> {
    private final Retryer retryer;
    private final Request request;
    private final AtomicBoolean succeeded = new AtomicBoolean();
    private final AtomicBoolean retried = new AtomicBoolean();

    public RetryableRequest(Request request) {
        this.retryer = RetryerBuilder.withRetryListener(this).build();
        this.request = request;
    }

    public void execute() {
        retryer.call(new Callable<Boolean>() {
            public Boolean call() {
                request.execute();
                // Here you modify `succeeded`.
            }
        });
    }

    public void onRetry(Attempt<Boolean> retry) {
        if (!retry.hasResult())
            retried.set(true);
    }

    public boolean executionWasRetried() {
        return retried.get();
    }

    public boolean executionSucceeded() {
        return succeeded.get();
    }
}

JensRantil avatar Feb 26 '16 14:02 JensRantil

I get an error: for implements RetryListener<Boolean> {

Error:(15, 48) java: type com.github.rholder.retry.RetryListener does not take parameters

elad2109 avatar Feb 26 '16 21:02 elad2109

why are these atomic?

private final AtomicBoolean succeeded = new AtomicBoolean();
private final AtomicBoolean retried = new AtomicBoolean();

I mean, should I create new listener to each request? each listener have a request member and thus i don't need thread safety (atomic boolean). no?

elad2109 avatar Feb 26 '16 22:02 elad2109

what does this mean retry.getNumerOfAttampts() == 1 ?

  1. The first try ever has been done? e.g. http send and returned

Or 2) These has been a retry after the a failure (retry-predicate returned false)? http send and returned failure, then we sent a retry already.

elad2109 avatar Feb 27 '16 12:02 elad2109

I get an error: for implements RetryListener<Boolean> {

I never compiled my code so I'm afraid you will have to take it with a grain of salt. :)

why are these atomic?

Because Java closures can't modify variables outside of its scope (since they need to be final). Using Atomic* classes circumvents that restriction.

what does this mean retry.getNumerOfAttampts() == 1 ?

What type is retry? Have you checked the JavaDoc for the method? See http://rholder.github.io/guava-retrying/javadoc/2.0.0/.

I mean, should I create new listener to each request?

I guess that really depends if you decide to keep any state in it or not. In my example above I store my state in RetryableRequest. That way, it's totally fine to create a new temporary listener for every request.

each listener have a request member and thus i don't need thread safety (atomic boolean). no?

Like I said :point_up:, the Atomic* classes aren't really used for thread safety, but rather working around Java limitations.

JensRantil avatar Feb 27 '16 22:02 JensRantil