-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested retries, how to prevent duplicate retrying? #379
Comments
I now came up with something like:
But I do not know if that is the most elegant way to do that. |
I don't understand what behavior you're trying to achieve. You want But you don't want it to retry if a particular method that Is the idea that an AssertionError thrown from These are weird semantics, very non-modular. And trying handle AssertionErrors at all feels dangerous. But assuming that's really what you want, then you could convert the AssertionError thrown by @SuppressWarnings("unchecked")
public static void aaa() {
try {
Failsafe.with(retryAssertionErrorOnce).run(() -> {
System.out.println("aaa");
bbb();
});
} catch (FailsafeException ex) {
if (ex.getCause() instanceof AssertionError) throw (AssertionError) ex.getCause();
throw ex;
}
}
public static void bbb() {
System.out.println("bbb");
ccc();
ddd();
}
public static void ccc() {
System.out.println("ccc");
}
@SuppressWarnings("unchecked")
public static void ddd() {
Failsafe.with(wrapAssertionError, retryAssertionErrorOnce).run(() -> {
System.out.println("ddd");
throw new AssertionError("ddd");
});
}
static RetryPolicy retryAssertionErrorOnce = RetryPolicy.builder()
.withMaxRetries(1)
.handle(AssertionError.class)
.build();
static Fallback wrapAssertionError =
Fallback.builderOfException(e -> new FailsafeException(e.getLastException()))
.handle(AssertionError.class)
.build();
public static void main(String[] args) {
MyClass.aaa();
MyClass.bbb();
} This produces the output you were hoping for, but again, this all seems highly suspect to begin with. |
Thank you, I was not aware of the possibility which you have shown in your example. What I was looking was a kind of "circuit breaker" for retries I guess. Lets assume there are nested retries. It does not matter what they do for the example. If a retry fails in one of the nested retry methods then, depending on the concrete case, it might be useless if the outer retry methods perform a retry on failure, because it would start the inner retries all over again, but it would be useless. That can be handled with different exception types, but I was looking for a more elegant and safe way. Like if a retry policy can be configured to signal outer retry methods not to retry if they catch this signal. I do not know the Failsafe framework so much, but maybe if it would then throw a "FailsafeDoNotRetryException", then the outer retry blocks would not attempt to retry but fail instantly. I am not sure if that makes sense. If not, no need to waste your time on that. What I wanted to achieve I could do now. |
You don't need a specialized exception type for that effect: Just throw an exception that isn't handled by any of outer Failsafe executors. That's what the code I presented above does, except I added code to translate that exception back to the original type. It's simpler without that code: public static void aaa() {
Failsafe.with(retryAssertionErrorOnce).run(() -> {
System.out.println("aaa");
bbb();
});
}
public static void bbb() {
System.out.println("bbb");
ccc();
ddd();
}
public static void ccc() {
System.out.println("ccc");
}
public static void ddd() {
Failsafe.with(wrapAssertionError, retryAssertionErrorOnce).run(() -> {
System.out.println("ddd");
throw new AssertionError("ddd");
});
}
public static void main(String[] args) {
MyClass.aaa();
MyClass.bbb();
}
static RetryPolicy<Void> retryAssertionErrorOnce = RetryPolicy.<Void>builder()
.withMaxRetries(1)
.handle(AssertionError.class)
.build();
static Fallback<Void> wrapAssertionError =
Fallback.<Void>builderOfException(e -> new FailsafeException(e.getLastException()))
.handle(AssertionError.class)
.build(); |
Thank you. |
I wonder how I can do something with Failsafe.
If methods which do a retry with Failsafe are nested then how can I prevent in the outter method that a retry is performed when an exception is thrown after the last retry of a inner method?
I would like to use the same Exception type in both
aaa()
and inddd()
,AssertionError.class
.The console output should be:
But it is:
I guess it could be done if there would be something like a marker or so, to flag the exception thrown by a inner retry method so that it if the flag is present it does not do a retry in the outter method, even if the exception types match.
The text was updated successfully, but these errors were encountered: