Skip to content

Commit b1408f0

Browse files
More aggressive retry strategy for NIO
(but only when OptionMaxChannelReopens is set)
1 parent 8293249 commit b1408f0

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

google-cloud-contrib/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageReadChannel.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,24 @@ public int read(ByteBuffer dst) throws IOException {
109109
amt = channel.read(dst);
110110
break;
111111
} catch (StorageException exs) {
112-
if (exs.getMessage().contains("Connection closed prematurely") && reopens < maxChannelReopens) {
113-
// this error isn't marked as retryable since the channel is closed;
112+
if (reopens < maxChannelReopens && (
113+
exs.getMessage().contains("Connection closed prematurely")
114+
|| exs.getCause() instanceof javax.net.ssl.SSLHandshakeException
115+
|| exs.getCause() instanceof java.io.EOFException
116+
|| exs.getCause() instanceof java.net.SocketTimeoutException
117+
)) {
118+
// these errors aren't marked as retryable since the channel is closed;
114119
// but here at this higher level we can retry it.
115120
reopens++;
116121
sleepForAttempt(reopens);
117122
innerOpen();
118123
continue;
119-
} else if ((exs.getCode() == 500 || exs.getCode() == 503) && retries < maxRetries) {
124+
} else if ((exs.isRetryable() || exs.getCode() == 500 || exs.getCode() == 503) && retries < maxRetries) {
120125
retries++;
121126
sleepForAttempt(retries);
122127
continue;
123128
}
124-
throw exs;
129+
throw new StorageException(exs.getCode(), "Retry failed", exs);
125130
}
126131
}
127132
if (amt > 0) {
@@ -136,8 +141,13 @@ public int read(ByteBuffer dst) throws IOException {
136141
}
137142

138143
private void sleepForAttempt(int attempt) {
144+
long delay = 500;
145+
// exponential backoff
146+
for (int i=0; i<attempt; i++) {
147+
delay *= 2;
148+
}
139149
try {
140-
Thread.sleep((attempt - 1) * 500);
150+
Thread.sleep(delay);
141151
} catch (InterruptedException iex) {
142152
// reset interrupt flag
143153
Thread.currentThread().interrupt();

0 commit comments

Comments
 (0)