Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.

Commit a269139

Browse files
committed
#27: Query rate limit using GitHub API.
1 parent 0fe9fb9 commit a269139

File tree

1 file changed

+64
-12
lines changed

1 file changed

+64
-12
lines changed
Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.github.maven.plugins.core;
22

3-
import com.github.maven.plugins.core.egit.GitHubClientEgit;
4-
import com.google.common.util.concurrent.RateLimiter;
3+
import static java.lang.Math.max;
4+
import static java.lang.System.currentTimeMillis;
55

66
import java.io.IOException;
77
import java.net.HttpURLConnection;
88

9+
import com.github.maven.plugins.core.egit.GitHubClientEgit;
10+
import com.google.common.util.concurrent.RateLimiter;
11+
912
public class RateLimitedGitHubClient extends GitHubClientEgit {
1013

11-
/**
12-
* AS per https://github.com/octokit/octokit.net/issues/638#issuecomment-67795998,
13-
* it seems that GitHub only allow 20 API calls per 1-minute period
14-
*/
15-
private RateLimiter rateLimiter = RateLimiter.create(20.0/60.0);
14+
private volatile RateLimiter rateLimiter;
1615

1716
public RateLimitedGitHubClient() {
1817
super();
@@ -28,25 +27,78 @@ public RateLimitedGitHubClient(String hostname, int port, String scheme) {
2827

2928
@Override
3029
protected HttpURLConnection createDelete(String uri) throws IOException {
31-
//rateLimiter.acquire();
3230
return super.createDelete(uri);
3331
}
3432

3533
@Override
3634
protected HttpURLConnection createGet(String uri) throws IOException {
37-
//rateLimiter.acquire();
3835
return super.createGet(uri);
3936
}
4037

4138
@Override
4239
protected HttpURLConnection createPost(String uri) throws IOException {
43-
rateLimiter.acquire();
40+
rateLimiter().acquire();
4441
return super.createPost(uri);
4542
}
4643

4744
@Override
4845
protected HttpURLConnection createPut(String uri) throws IOException {
49-
rateLimiter.acquire();
46+
rateLimiter().acquire();
5047
return super.createPut(uri);
5148
}
52-
}
49+
50+
private RateLimiter rateLimiter() {
51+
final RateLimiter rateLimiter = this.rateLimiter;
52+
53+
if (rateLimiter != null) {
54+
return rateLimiter;
55+
}
56+
57+
return initializeRateLimiter();
58+
}
59+
60+
private synchronized RateLimiter initializeRateLimiter() {
61+
62+
if (rateLimiter != null) {
63+
return rateLimiter;
64+
}
65+
66+
HttpURLConnection connection = null;
67+
68+
try {
69+
70+
//
71+
// Query rate limit.
72+
//
73+
74+
connection = createGet("/rate_limit");
75+
76+
final int remaining = connection.getHeaderFieldInt("X-RateLimit-Remaining", -1);
77+
final int reset = connection.getHeaderFieldInt("X-RateLimit-Reset", -1);
78+
final int now = (int) (currentTimeMillis() / 1000);
79+
80+
//
81+
// Calculate the sustained request rate until the limits are reset.
82+
//
83+
84+
return rateLimiter = RateLimiter.create((double) remaining / max(reset - now, 1));
85+
86+
} catch (Exception e) {
87+
88+
//
89+
// Fall back to 20 requests per minute.
90+
//
91+
// As per https://github.com/octokit/octokit.net/issues/638#issuecomment-67795998,
92+
// it seems that GitHub only allow 20 API calls per 1-minute period
93+
//
94+
95+
return rateLimiter = RateLimiter.create(20. / 60.);
96+
97+
} finally {
98+
99+
if (connection != null) {
100+
connection.disconnect();
101+
}
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)