Skip to content

Commit e177f9a

Browse files
author
Robert Fink
authored
Add "Retry after" support to QosException.Throttle (#40)
1 parent 6ba7f4e commit e177f9a

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

errors/src/main/java/com/palantir/remoting/api/errors/QosException.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
import com.palantir.logsafe.SafeArg;
2121
import com.palantir.logsafe.SafeLoggable;
2222
import java.net.URL;
23+
import java.time.Duration;
2324
import java.util.ArrayList;
2425
import java.util.List;
26+
import java.util.Optional;
2527

2628
/**
2729
* An exception raised by a service to indicate a potential Quality-of-Service problem, specifically requesting that the
@@ -32,7 +34,9 @@
3234
public abstract class QosException extends RuntimeException {
3335

3436
// Not meant for external subclassing.
35-
private QosException() {}
37+
private QosException(String message) {
38+
super(message);
39+
}
3640

3741
abstract <T> T accept(Visitor<T> visitor);
3842

@@ -47,7 +51,15 @@ public interface Visitor<T> {
4751
* may retry against an arbitrary node of this service.
4852
*/
4953
public static Throttle throttle() {
50-
return new Throttle();
54+
return new Throttle(Optional.empty());
55+
}
56+
57+
/**
58+
* Like {@link #throttle()}, but additionally requests that the client wait for at least the given duration before
59+
* retrying the request.
60+
*/
61+
public static Throttle throttle(Duration duration) {
62+
return new Throttle(Optional.of(duration));
5163
}
5264

5365
/**
@@ -59,16 +71,25 @@ public static RetryOther retryOther(URL redirectTo) {
5971
}
6072

6173
/**
62-
* An exception indicating that (this node of) this service are currently unavailable and the client may try again
63-
* at a later time, possibly against a different node of this service.
74+
* An exception indicating that (this node of) this service is currently unavailable and the client may try again at
75+
* a later time, possibly against a different node of this service.
6476
*/
6577
public static Unavailable unavailable() {
6678
return new Unavailable();
6779
}
6880

6981
/** See {@link #throttle}. */
7082
public static final class Throttle extends QosException {
71-
private Throttle() {}
83+
private final Optional<Duration> retryAfter;
84+
85+
private Throttle(Optional<Duration> retryAfter) {
86+
super("Suggesting request throttling with optional retryAfter duration: " + retryAfter);
87+
this.retryAfter = retryAfter;
88+
}
89+
90+
public Optional<Duration> getRetryAfter() {
91+
return retryAfter;
92+
}
7293

7394
@Override
7495
<T> T accept(Visitor<T> visitor) {
@@ -81,6 +102,7 @@ public static final class RetryOther extends QosException implements SafeLoggabl
81102
private final URL redirectTo;
82103

83104
private RetryOther(URL redirectTo) {
105+
super("Suggesting request retry against: " + redirectTo.toString());
84106
this.redirectTo = redirectTo;
85107
}
86108

@@ -109,7 +131,9 @@ public List<Arg<?>> getArgs() {
109131

110132
/** See {@link #unavailable}. */
111133
public static final class Unavailable extends QosException {
112-
private Unavailable() {}
134+
private Unavailable() {
135+
super("Server unavailable");
136+
}
113137

114138
@Override
115139
<T> T accept(Visitor<T> visitor) {

errors/src/test/java/com/palantir/remoting/api/errors/QosExceptionTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.assertj.core.api.Assertions.assertThat;
2121

22+
import java.net.URL;
2223
import org.junit.Test;
2324

2425
public final class QosExceptionTest {
@@ -43,7 +44,8 @@ public Class visit(QosException.Unavailable exception) {
4344
};
4445

4546
assertThat(QosException.throttle().accept(visitor)).isEqualTo(QosException.Throttle.class);
46-
assertThat(QosException.retryOther(null).accept(visitor)).isEqualTo(QosException.RetryOther.class);
47+
assertThat(QosException.retryOther(new URL("http://foo")).accept(visitor))
48+
.isEqualTo(QosException.RetryOther.class);
4749
assertThat(QosException.unavailable().accept(visitor)).isEqualTo(QosException.Unavailable.class);
4850
}
4951
}

0 commit comments

Comments
 (0)