Browse Source

Retry logic

pull/7526/head
chrislu 4 weeks ago
parent
commit
ed21e2d806
  1. 47
      other/java/client/src/main/java/seaweedfs/client/SeaweedWrite.java

47
other/java/client/src/main/java/seaweedfs/client/SeaweedWrite.java

@ -67,14 +67,43 @@ public class SeaweedWrite {
final long bytesOffset,
final long bytesLength,
final String path) throws IOException {
FilerProto.AssignVolumeResponse response = filerClient.getBlockingStub().assignVolume(
// Retry assignVolume call for transient network/server errors
FilerProto.AssignVolumeResponse response = null;
IOException lastException = null;
int maxRetries = 3;
for (int attempt = 0; attempt < maxRetries; attempt++) {
try {
response = filerClient.getBlockingStub().assignVolume(
FilerProto.AssignVolumeRequest.newBuilder()
.setCollection(Strings.isNullOrEmpty(collection) ? filerClient.getCollection() : collection)
.setReplication(Strings.isNullOrEmpty(replication) ? filerClient.getReplication() : replication)
.setCollection(
Strings.isNullOrEmpty(collection) ? filerClient.getCollection() : collection)
.setReplication(
Strings.isNullOrEmpty(replication) ? filerClient.getReplication() : replication)
.setDataCenter("")
.setTtlSec(0)
.setPath(path)
.build());
break; // Success, exit retry loop
} catch (io.grpc.StatusRuntimeException e) {
lastException = new IOException(
"assignVolume failed (attempt " + (attempt + 1) + "/" + maxRetries + "): " + e.getMessage(), e);
if (attempt < maxRetries - 1) {
try {
Thread.sleep(100 * (attempt + 1)); // Exponential backoff: 100ms, 200ms, 300ms
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted during retry", ie);
}
}
}
}
if (response == null) {
throw lastException != null ? lastException
: new IOException("assignVolume failed after " + maxRetries + " attempts");
}
if (!Strings.isNullOrEmpty(response.getError())) {
throw new IOException(response.getError());
@ -83,7 +112,8 @@ public class SeaweedWrite {
String fileId = response.getFileId();
String auth = response.getAuth();
String targetUrl = filerClient.getChunkUrl(fileId, response.getLocation().getUrl(), response.getLocation().getPublicUrl());
String targetUrl = filerClient.getChunkUrl(fileId, response.getLocation().getUrl(),
response.getLocation().getPublicUrl());
ByteString cipherKeyString = com.google.protobuf.ByteString.EMPTY;
byte[] cipherKey = null;
@ -110,15 +140,15 @@ public class SeaweedWrite {
final FilerProto.Entry.Builder entry) throws IOException {
synchronized (entry) {
List<FilerProto.FileChunk> chunks = FileChunkManifest.maybeManifestize(filerClient, entry.getChunksList(), parentDirectory);
List<FilerProto.FileChunk> chunks = FileChunkManifest.maybeManifestize(filerClient, entry.getChunksList(),
parentDirectory);
entry.clearChunks();
entry.addAllChunks(chunks);
filerClient.getBlockingStub().createEntry(
FilerProto.CreateEntryRequest.newBuilder()
.setDirectory(parentDirectory)
.setEntry(entry)
.build()
);
.build());
}
}
@ -162,7 +192,8 @@ public class SeaweedWrite {
try {
if (response.getStatusLine().getStatusCode() / 100 != 2) {
if (response.getEntity().getContentType() != null && response.getEntity().getContentType().getValue().equals("application/json")) {
if (response.getEntity().getContentType() != null
&& response.getEntity().getContentType().getValue().equals("application/json")) {
throw new IOException(EntityUtils.toString(response.getEntity(), "UTF-8"));
} else {
throw new IOException(response.getStatusLine().getReasonPhrase());

Loading…
Cancel
Save