Skip to content

Commit 50d4ae6

Browse files
authored
Merge pull request hub4j#1298 from bitwiseman/task/deprecation2
Deprecate limit handlers using HttpURLConnection
2 parents 1535817 + 8effe61 commit 50d4ae6

16 files changed

+417
-189
lines changed

src/main/java/org/kohsuke/github/AbuseLimitHandler.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
* Pluggable strategy to determine what to do when the API abuse limit is hit.
1313
*
1414
* @author Kohsuke Kawaguchi
15-
* @see GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler) GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler)
15+
* @see GitHubBuilder#withAbuseLimitHandler(GitHubAbuseLimitHandler)
16+
* GitHubBuilder#withAbuseLimitHandler(GitHubAbuseLimitHandler)
1617
* @see <a href="https://developer.github.com/v3/#abuse-rate-limits">documentation</a>
1718
* @see RateLimitHandler
1819
*/
19-
public abstract class AbuseLimitHandler {
20+
@Deprecated
21+
public abstract class AbuseLimitHandler extends GitHubAbuseLimitHandler {
2022

2123
/**
2224
* Called when the library encounters HTTP error indicating that the API abuse limit is reached.
@@ -37,7 +39,7 @@ public abstract class AbuseLimitHandler {
3739
*
3840
*/
3941
public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException {
40-
GHIOException e = new HttpException("Abuse limit violation",
42+
GHIOException e = new HttpException("Abuse limit reached",
4143
connectorResponse.statusCode(),
4244
connectorResponse.header("Status"),
4345
connectorResponse.request().url().toString()).withResponseHeaderFields(connectorResponse.allHeaders());
@@ -66,12 +68,12 @@ public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws I
6668
*
6769
*/
6870
@Deprecated
69-
public void onError(IOException e, HttpURLConnection uc) throws IOException {
70-
}
71+
public abstract void onError(IOException e, HttpURLConnection uc) throws IOException;
7172

7273
/**
7374
* Wait until the API abuse "wait time" is passed.
7475
*/
76+
@Deprecated
7577
public static final AbuseLimitHandler WAIT = new AbuseLimitHandler() {
7678
@Override
7779
public void onError(IOException e, HttpURLConnection uc) throws IOException {
@@ -94,10 +96,11 @@ private long parseWaitTime(HttpURLConnection uc) {
9496
/**
9597
* Fail immediately.
9698
*/
99+
@Deprecated
97100
public static final AbuseLimitHandler FAIL = new AbuseLimitHandler() {
98101
@Override
99102
public void onError(IOException e, HttpURLConnection uc) throws IOException {
100-
throw (IOException) new IOException("Abuse limit reached").initCause(e);
103+
throw e;
101104
}
102105
};
103106
}

src/main/java/org/kohsuke/github/GitHub.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ public class GitHub {
113113
*/
114114
GitHub(String apiUrl,
115115
GitHubConnector connector,
116-
RateLimitHandler rateLimitHandler,
117-
AbuseLimitHandler abuseLimitHandler,
116+
GitHubRateLimitHandler rateLimitHandler,
117+
GitHubAbuseLimitHandler abuseLimitHandler,
118118
GitHubRateLimitChecker rateLimitChecker,
119119
AuthorizationProvider authorizationProvider) throws IOException {
120120
if (authorizationProvider instanceof DependentAuthorizationProvider) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.kohsuke.github;
2+
3+
import org.kohsuke.github.connector.GitHubConnectorResponse;
4+
5+
import java.io.IOException;
6+
import java.net.HttpURLConnection;
7+
8+
import javax.annotation.Nonnull;
9+
10+
/**
11+
* Pluggable strategy to determine what to do when the API rate limit is reached.
12+
*
13+
* @author Kohsuke Kawaguchi
14+
* @see GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler) GitHubBuilder#withRateLimitHandler(AbuseLimitHandler)
15+
* @see GitHubRateLimitHandler
16+
*/
17+
public abstract class GitHubAbuseLimitHandler extends GitHubConnectorResponseErrorHandler {
18+
19+
@Override
20+
boolean isError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException {
21+
return connectorResponse.statusCode() == HttpURLConnection.HTTP_FORBIDDEN
22+
&& connectorResponse.header("Retry-After") != null;
23+
}
24+
25+
/**
26+
* Called when the library encounters HTTP error indicating that the API abuse limit is reached.
27+
*
28+
* <p>
29+
* Any exception thrown from this method will cause the request to fail, and the caller of github-api will receive
30+
* an exception. If this method returns normally, another request will be attempted. For that to make sense, the
31+
* implementation needs to wait for some time.
32+
*
33+
* @param connectorResponse
34+
* Response information for this request.
35+
* @throws IOException
36+
* on failure
37+
* @see <a href="https://developer.github.com/v3/#abuse-rate-limits">API documentation from GitHub</a>
38+
* @see <a href=
39+
* "https://developer.github.com/v3/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits">Dealing
40+
* with abuse rate limits</a>
41+
*
42+
*/
43+
public abstract void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException;
44+
}

src/main/java/org/kohsuke/github/GitHubBuilder.java

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.kohsuke.github.authorization.AuthorizationProvider;
55
import org.kohsuke.github.authorization.ImmutableAuthorizationProvider;
66
import org.kohsuke.github.connector.GitHubConnector;
7+
import org.kohsuke.github.connector.GitHubConnectorResponse;
78
import org.kohsuke.github.extras.ImpatientHttpConnector;
89
import org.kohsuke.github.internal.GitHubConnectorHttpConnectorAdapter;
910

@@ -34,8 +35,8 @@ public class GitHubBuilder implements Cloneable {
3435

3536
private GitHubConnector connector;
3637

37-
private RateLimitHandler rateLimitHandler = RateLimitHandler.WAIT;
38-
private AbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT;
38+
private GitHubRateLimitHandler rateLimitHandler = RateLimitHandler.WAIT;
39+
private GitHubAbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT;
3940
private GitHubRateLimitChecker rateLimitChecker = new GitHubRateLimitChecker();
4041
/* private */ AuthorizationProvider authorizationProvider = AuthorizationProvider.ANONYMOUS;
4142

@@ -334,6 +335,7 @@ public GitHubBuilder withJwtToken(String jwtToken) {
334335
* the connector
335336
* @return the git hub builder
336337
*/
338+
@Deprecated
337339
public GitHubBuilder withConnector(@Nonnull HttpConnector connector) {
338340
return withConnector(GitHubConnectorHttpConnectorAdapter.adapt(connector));
339341
}
@@ -373,6 +375,32 @@ public GitHubBuilder withConnector(GitHubConnector connector) {
373375
* @see #withRateLimitChecker(RateLimitChecker)
374376
*/
375377
public GitHubBuilder withRateLimitHandler(RateLimitHandler handler) {
378+
return withRateLimitHandler((GitHubRateLimitHandler) handler);
379+
}
380+
381+
/**
382+
* Adds a {@link GitHubRateLimitHandler} to this {@link GitHubBuilder}.
383+
* <p>
384+
* GitHub allots a certain number of requests to each user or application per period of time (usually per hour). The
385+
* number of requests remaining is returned in the response header and can also be requested using
386+
* {@link GitHub#getRateLimit()}. This requests per interval is referred to as the "rate limit".
387+
* </p>
388+
* <p>
389+
* When the remaining number of requests reaches zero, the next request will return an error. If this happens,
390+
* {@link GitHubRateLimitHandler#onError(GitHubConnectorResponse)} will be called.
391+
* </p>
392+
* <p>
393+
* NOTE: GitHub treats clients that exceed their rate limit very harshly. If possible, clients should avoid
394+
* exceeding their rate limit. Consider adding a {@link RateLimitChecker} to automatically check the rate limit for
395+
* each request and wait if needed.
396+
* </p>
397+
*
398+
* @param handler
399+
* the handler
400+
* @return the git hub builder
401+
* @see #withRateLimitChecker(RateLimitChecker)
402+
*/
403+
public GitHubBuilder withRateLimitHandler(GitHubRateLimitHandler handler) {
376404
this.rateLimitHandler = handler;
377405
return this;
378406
}
@@ -389,7 +417,24 @@ public GitHubBuilder withRateLimitHandler(RateLimitHandler handler) {
389417
* the handler
390418
* @return the git hub builder
391419
*/
420+
@Deprecated
392421
public GitHubBuilder withAbuseLimitHandler(AbuseLimitHandler handler) {
422+
return withAbuseLimitHandler((GitHubAbuseLimitHandler) handler);
423+
}
424+
425+
/**
426+
* Adds a {@link GitHubAbuseLimitHandler} to this {@link GitHubBuilder}.
427+
* <p>
428+
* When a client sends too many requests in a short time span, GitHub may return an error and set a header telling
429+
* the client to not make any more request for some period of time. If this happens,
430+
* {@link GitHubAbuseLimitHandler#onError(GitHubConnectorResponse)} will be called.
431+
* </p>
432+
*
433+
* @param handler
434+
* the handler
435+
* @return the git hub builder
436+
*/
437+
public GitHubBuilder withAbuseLimitHandler(GitHubAbuseLimitHandler handler) {
393438
this.abuseLimitHandler = handler;
394439
return this;
395440
}

0 commit comments

Comments
 (0)