GitHub auth: maintain rate limit reset information, track token with highest remaining requests
This commit is contained in:
parent
fe279e4a75
commit
997e6a6f43
|
@ -115,36 +115,60 @@ function sendTokenToAllServers(token) {
|
|||
|
||||
// Track rate limit requests remaining.
|
||||
|
||||
var reqRemaining = new Map();
|
||||
var lowestReqRemaining = Infinity, lowestReqRemainingToken;
|
||||
var reqRemaining = new Map(); // From token to requests remaining.
|
||||
var reqReset = new Map(); // From token to timestamp.
|
||||
var highestReqRemaining = 0, highestReqRemainingToken;
|
||||
|
||||
// Set lowestReqRemaining* variables if the token / requests remaining
|
||||
// combination passed as a parameter is lower than previously registered.
|
||||
function setLowestReqRemaining(token, reqs) {
|
||||
if (reqs <= lowestReqRemaining) {
|
||||
lowestReqRemaining = reqs;
|
||||
lowestReqRemainingToken = token;
|
||||
// Set highestReqRemaining* variables if the token / requests remaining
|
||||
// combination passed as a parameter is higher than previously registered.
|
||||
function setHighestReqRemaining(token, reqs) {
|
||||
// Equality is allowed to ensure that we have a token set as
|
||||
// highestReqRemainingToken (or else there are no user tokens given).
|
||||
if (reqs >= highestReqRemaining) {
|
||||
highestReqRemaining = reqs;
|
||||
highestReqRemainingToken = token;
|
||||
}
|
||||
}
|
||||
|
||||
// token: client token as a string.
|
||||
// reqs: number of requests remaining.
|
||||
function setReqRemaining(token, reqs) {
|
||||
setLowestReqRemaining(token, reqs);
|
||||
// reset: timestamp when the number of remaining requests is reset.
|
||||
function setReqRemaining(token, reqs, reset) {
|
||||
setHighestReqRemaining(token, reqs);
|
||||
reqRemaining.set(token, reqs);
|
||||
reqReset.set(token, reset);
|
||||
}
|
||||
|
||||
// Retrieve a user token if there is one for which we believe there are requests
|
||||
// remaining. Return undefined if we could not find one.
|
||||
function getReqRemainingToken() {
|
||||
if (highestReqRemaining > 0) {
|
||||
return highestReqRemainingToken;
|
||||
} else {
|
||||
// Go through the user tokens, keep the first one which has reset.
|
||||
var now = +new Date();
|
||||
for (var token of reqReset.keys()) {
|
||||
if (reqReset.get(token) < now) {
|
||||
// We are past the rate limit reset.
|
||||
highestReqRemainingToken = token;
|
||||
return highestReqRemainingToken
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rmReqRemaining(token) {
|
||||
reqRemaining.delete(token);
|
||||
if (lowestReqRemainingToken === token) {
|
||||
lowestReqRemaining = Infinity;
|
||||
lowestReqRemainingToken = undefined;
|
||||
reqRemaining.forEach(setLowestReqRemaining);
|
||||
reqReset.delete(token);
|
||||
if (highestReqRemainingToken === token) {
|
||||
highestReqRemaining = 0;
|
||||
highestReqRemainingToken = undefined;
|
||||
reqRemaining.forEach(setHighestReqRemaining);
|
||||
}
|
||||
}
|
||||
|
||||
function addGithubToken(token) {
|
||||
setReqRemaining(token, Infinity);
|
||||
setReqRemaining(token, 0, +new Date());
|
||||
// Insert it only if it is not registered yet.
|
||||
if (githubUserTokens.data.indexOf(token) === -1) {
|
||||
githubUserTokens.data.push(token);
|
||||
|
@ -177,10 +201,9 @@ function githubRequest(request, url, query, cb) {
|
|||
'User-Agent': 'Shields.io',
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
};
|
||||
var githubToken;
|
||||
var githubToken = getReqRemainingToken();
|
||||
|
||||
if (lowestReqRemainingToken != null && lowestReqRemaining > 0) {
|
||||
githubToken = lowestReqRemainingToken;
|
||||
if (githubToken != null) {
|
||||
headers['Authorization'] = 'token ' + githubToken;
|
||||
} else if (serverSecrets && serverSecrets.gh_client_id) {
|
||||
// Using our OAuth App secret grants us 5000 req/hour
|
||||
|
@ -197,7 +220,8 @@ function githubRequest(request, url, query, cb) {
|
|||
rmGithubToken(githubToken);
|
||||
} else {
|
||||
var remaining = +res.headers['x-ratelimit-remaining'];
|
||||
setReqRemaining(githubToken, remaining);
|
||||
var reset = +res.headers['x-ratelimit-reset'];
|
||||
setReqRemaining(githubToken, remaining, reset);
|
||||
}
|
||||
}
|
||||
cb(err, res, buffer);
|
||||
|
|
Loading…
Reference in New Issue
Block a user