feat(http-client): "Handle" GOAWAY by retrying. Should be fine given the fact we only allow 3 retries.
ci/woodpecker/push/woodpecker Pipeline failed Details

This commit is contained in:
Johannes Frohnmeyer 2023-10-03 19:32:34 +02:00
parent 749b475d0d
commit 53cb166568
Signed by: Johannes
GPG Key ID: E76429612C2929F4
1 changed files with 12 additions and 5 deletions

View File

@ -9,9 +9,7 @@ import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -71,6 +69,7 @@ public class HttpClient {
private int retryAfterDefault = 5000;
private int retryAfterMax = 15000;
private int retryLimit = 3;
private List<Exception> retryExceptions = null;
public Request(Method method, String url) throws URISyntaxException {
this.url = url.replace(" ", "%20");
@ -156,7 +155,11 @@ public class HttpClient {
private <T> T _send(String accept, HttpResponse.BodyHandler<T> responseBodyHandler) throws IOException {
sent++;
if (sent > retryLimit) throw new IOException("Attempted third redirect, stopping");
if (sent > retryLimit) {
IOException e = new IOException("Attempted to reconnect/redirect " + sent + " times, which is more than the permitted " + retryLimit + ". Stopping");
if (retryExceptions != null) for (Exception ex : retryExceptions) e.addSuppressed(ex);
throw e;
}
builder.header("Accept", accept);
if (method != null) builder.method(method.name(), HttpRequest.BodyPublishers.noBody());
if (PROXY_AUTH != null) builder.header("Proxy-Authorization", PROXY_AUTH);
@ -166,6 +169,10 @@ public class HttpClient {
res = CLIENT.send(builder.build(), responseBodyHandler);
} catch (InterruptedException e) {
throw new IOException("Could not send request", e);
} catch (IOException e) {
if (e.getMessage().contains("GOAWAY received")) {
return handleRetryAfter(accept, responseBodyHandler, Math.min(1000, retryAfterMax));
} else throw new IOException("Could not send request", e);
}
if (res.statusCode() / 100 == 2) return res.body();
Optional<String> location = res.headers().firstValue("location");
@ -196,7 +203,7 @@ public class HttpClient {
case 500, 502, 503, 504, 507 -> {
// CurseForge serverside error
if (CURSEFORGE_API.test(url)) {
yield handleRetryAfter(accept, responseBodyHandler, 1000);
yield handleRetryAfter(accept, responseBodyHandler, Math.min(1000, retryAfterMax));
}
throw new IOException("Unexpected serverside error: " + res.statusCode() + exceptionSuffix);
}