From: gmungoc Date: Fri, 11 Mar 2016 12:08:06 +0000 (+0000) Subject: JAL-1705 check Retry-After response header X-Git-Tag: Release_2_10_0~296^2~8 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=b9df385dd6b61f92577c68b9f39ca0f9fc4d3993;p=jalview.git JAL-1705 check Retry-After response header --- diff --git a/src/jalview/ext/ensembl/EnsemblRestClient.java b/src/jalview/ext/ensembl/EnsemblRestClient.java index 1c47373..34f8816 100644 --- a/src/jalview/ext/ensembl/EnsemblRestClient.java +++ b/src/jalview/ext/ensembl/EnsemblRestClient.java @@ -44,6 +44,11 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher private static long lastCheck = -1; + /* + * absolute time to wait till if we overloaded the REST service + */ + private static long retryAfter; + protected volatile boolean inProgress = false; /** @@ -228,6 +233,8 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher } // System.out.println(getClass().getName() + " took " // + (System.currentTimeMillis() - now) + "ms to fetch"); + + checkRateLimits(connection); BufferedReader reader = null; reader = new BufferedReader(new InputStreamReader(response, "UTF-8")); @@ -235,6 +242,52 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher } /** + * Inspect response headers for any sign of server overload and respect any + * 'retry-after' directive + * + * @see https://github.com/Ensembl/ensembl-rest/wiki/Rate-Limits + * @param connection + */ + void checkRateLimits(HttpURLConnection connection) + { + // number of requests allowed per time interval: + String limit = connection.getHeaderField("X-RateLimit-Limit"); + // length of quota time interval in seconds: + // String period = connection.getHeaderField("X-RateLimit-Period"); + // seconds remaining until usage quota is reset: + String reset = connection.getHeaderField("X-RateLimit-Reset"); + // number of requests remaining from quota for current period: + String remaining = connection.getHeaderField("X-RateLimit-Remaining"); + // number of seconds to wait before retrying (if remaining == 0) + String retryDelay = connection.getHeaderField("Retry-After"); + + // to test: + // retryDelay = "5"; + + if (retryDelay != null) + { + System.err.println("Ensembl REST service rate limit exceeded, wait " + + retryDelay + " seconds before retrying"); + try + { + retryAfter = System.currentTimeMillis() + + (1000 * Integer.valueOf(retryDelay)); + } catch (NumberFormatException e) + { + System.err.println("Unexpected value for Retry-After: " + + retryDelay); + } + } + else + { + retryAfter = 0; + // debug: + // System.out.println(String.format( + // "%s Ensembl requests remaining of %s (reset in %ss)", + // remaining, limit, reset)); + } + } + /** * Rechecks if Ensembl is responding, unless the last check was successful and * the retest interval has not yet elapsed. Returns true if Ensembl is up, * else false. @@ -244,6 +297,21 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher protected boolean isEnsemblAvailable() { long now = System.currentTimeMillis(); + + /* + * check if we are waiting for 'Retry-After' to expire + */ + if (retryAfter > now) + { + System.err.println("Still " + (1 + (retryAfter - now) / 1000) + + " secs to wait before retrying Ensembl"); + return false; + } + else + { + retryAfter = 0; + } + boolean retest = now - lastCheck > RETEST_INTERVAL; if (ensemblRestAvailable && !retest) {