Skip to content
Snippets Groups Projects
Commit 7d50dd81 authored by Sander Østrem Fagernes's avatar Sander Østrem Fagernes
Browse files

Merge branch '59-fix-retry-shortcuts-on-1-status-code' into 'main'

Resolve "fix: Retry shortcuts on -1 status code"

Closes #59

See merge request !65
parents 324742f0 5daff904
No related branches found
No related tags found
1 merge request!65Resolve "fix: Retry shortcuts on -1 status code"
Pipeline #215664 passed with stages
in 2 minutes and 57 seconds
...@@ -8,64 +8,87 @@ import com.badlogic.gdx.Net.HttpResponse; ...@@ -8,64 +8,87 @@ import com.badlogic.gdx.Net.HttpResponse;
* Handles request and response from the HTTP request using * Handles request and response from the HTTP request using
* a passed callback function that treats request success, failure and cancellation. * a passed callback function that treats request success, failure and cancellation.
* Implements the retry tactic by resending the request on failure * Implements the retry tactic by resending the request on failure
* a few times with increasing backoff time between resends. * a few times with increasing backoff time between resends. Circuit pattern employed
* to limit the amount of retries.
*/ */
public class HTTPRequestHandler implements Net.HttpResponseListener { public class HTTPRequestHandler implements Net.HttpResponseListener {
private final HTTPRequestHandler instance = this;
private final Callback callback; private final Callback callback;
private final Net.HttpRequest request; private final Net.HttpRequest request;
private final int REQUEST_TIMEOUT = 6000;
private final int MAX_ATTEMPTS = 5;
private final int BACKOFF_TIME = 500;
private int attempts = 0; private int attempts = 0;
private final int MAX_ATTEMPTS = 3;
private final int BACKOFF_TIME = 300;
public HTTPRequestHandler(Callback callback, Net.HttpRequest request) { public HTTPRequestHandler(Callback callback, Net.HttpRequest request) {
this.callback = callback; this.callback = callback;
this.request = request; this.request = request;
this.request.setTimeOut(REQUEST_TIMEOUT);
} }
/** /**
* Send the HTTP request * Send the HTTP request, passing the send call to the render thread
*/ */
public void sendRequest() { public void sendRequest() {
Gdx.net.sendHttpRequest(request, this); Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
Gdx.net.sendHttpRequest(request, instance);
}
});
}
/**
* Retries sending the request as long as the attempts are not exhausted.
* The back-off time between each request increases with the number of attempts.
* @return {@code true} if a successful retry was made
* {@code false} otherwise
*/
private boolean retry() {
if (attempts < MAX_ATTEMPTS) {
attempts++;
try {
Thread.sleep((long) Math.pow(attempts, 1.3) * BACKOFF_TIME);
sendRequest();
return true;
} catch(InterruptedException e) {
System.err.println(e.getMessage());
}
}
return false;
} }
/** /**
* Request was successful and response received. Passes response body * Response received from server. Passing response to callback.
* to callback. * If callback returns {@code false}, request is retried.
* *
* @param httpResponse The {@link HttpResponse} with the HTTP response values. * @param httpResponse The {@link HttpResponse} with the HTTP response values.
*/ */
public void handleHttpResponse(HttpResponse httpResponse) { public void handleHttpResponse(HttpResponse httpResponse) {
if (!callback.onResult(httpResponse)) boolean succeeded = callback.onResult(httpResponse);
failed(new Throwable("Response returned with status code " +
if (!succeeded) failed(new Throwable("Response returned with status code " +
httpResponse.getStatus().getStatusCode())); httpResponse.getStatus().getStatusCode()));
} }
/** /**
* Request failed. Request will be retried until the attempts * Request failed. Request will be retried until the attempts
* have been exhausted with an increasing backoff time between each retry. * have been exhausted, at which point the callback is called.
* *
* @param t If the HTTP request failed because an Exception, t encapsulates it to give more information. * @param t If the HTTP request failed because an Exception, t encapsulates it to give more information.
*/ */
public void failed(Throwable t) { public void failed(Throwable t) {
if (attempts < MAX_ATTEMPTS) { boolean didRetry = retry();
attempts++;
try {
Thread.sleep((long) attempts * BACKOFF_TIME);
sendRequest();
return;
} catch(InterruptedException e) {
System.err.println(e.getMessage());
}
}
callback.onFailed(t); if (!didRetry) callback.onFailed(t);
} }
/** /**
* Request was cancelled * Request was cancelled. Nothing happens.
*/ */
public void cancelled() { public void cancelled() {
System.out.println("Request cancelled"); System.out.println("Request cancelled");
......
...@@ -276,7 +276,6 @@ public class FindGameController { ...@@ -276,7 +276,6 @@ public class FindGameController {
@Override @Override
public void onFailed(Throwable t) { public void onFailed(Throwable t) {
System.err.println("Check lobby status request failed:\n" + t); System.err.println("Check lobby status request failed:\n" + t);
exitLobby();
} }
}, new HttpRequestBuilder() }, new HttpRequestBuilder()
.newRequest() .newRequest()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment