All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kohsuke.github.RateLimitChecker Maven / Gradle / Ivy

The newest version!
package org.kohsuke.github;

import java.util.logging.Level;
import java.util.logging.Logger;

// TODO: Auto-generated Javadoc
/**
 * A GitHub API Rate Limit Checker called before each request
 *
 * 

* GitHub allots a certain number of requests to each user or application per period of time. The number of requests * remaining and the time when the number will be reset is returned in the response header and can also be requested * using {@link GitHub#getRateLimit()}. The "requests per interval" is referred to as the "rate limit". *

*

* GitHub prefers that clients stop before exceeding their rate limit rather than stopping after they exceed it. The * {@link RateLimitChecker} is called before each request to check the rate limit and wait if the checker criteria are * met. *

* * @author Liam Newman */ public abstract class RateLimitChecker { /** * Create default RateLimitChecker instance */ public RateLimitChecker() { } private static final Logger LOGGER = Logger.getLogger(RateLimitChecker.class.getName()); /** The Constant NONE. */ public static final RateLimitChecker NONE = new RateLimitChecker() { }; /** * Decides whether the current request exceeds the allowed "rate limit" budget. If this determines the rate limit * will be exceeded, this method should sleep for some amount of time and must return {@code true}. Implementers are * free to choose whatever strategy they prefer for what is considered to exceed the budget and how long to sleep. * *

* The caller of this method figures out which {@link GHRateLimit.Record} applies for the current request and * provides it to this method. *

*

* As long as this method returns {@code true} it is guaranteed that {@link GitHubRateLimitChecker} will retrieve * updated rate limit information and call this method again with {@code count} incremented by one. When this * checker returns {@code false}, the calling {@link GitHubRateLimitChecker} will let the request continue. *

*

* Rate limit reset times are only accurate to the second. Trying to sleep to exactly the reset time could result in * requests being sent before the new rate limit was available. For this reason, if this method returned * {@code true} at least once for a particular request, {@link GitHubRateLimitChecker} may choose to sleep for some * small additional between calls and before letting the request continue. *

* * @param rateLimitRecord * the current {@link GHRateLimit.Record} to check against. * @param count * the number of times in a row this method has been called for the current request * @return {@code false} if the current request does not exceed the allowed budget, {@code true} if the current * request exceeded the budget. * @throws InterruptedException * if the thread is interrupted while sleeping */ protected boolean checkRateLimit(GHRateLimit.Record rateLimitRecord, long count) throws InterruptedException { return false; } /** * Sleep until reset. * * @param record * the record * @return true, if successful * @throws InterruptedException * the interrupted exception */ protected final boolean sleepUntilReset(GHRateLimit.Record record) throws InterruptedException { // Sleep until reset long sleepMilliseconds = record.getResetDate().getTime() - System.currentTimeMillis(); if (sleepMilliseconds > 0) { String message = String.format( "GitHub API - Current quota has %d remaining of %d. Waiting for quota to reset at %tT.", record.getRemaining(), record.getLimit(), record.getResetDate()); LOGGER.log(Level.INFO, message); Thread.sleep(sleepMilliseconds); return true; } return false; } /** * A {@link RateLimitChecker} with a simple number as the limit. */ public static class LiteralValue extends RateLimitChecker { private final int sleepAtOrBelow; /** * Instantiates a new literal value. * * @param sleepAtOrBelow * the sleep at or below */ public LiteralValue(int sleepAtOrBelow) { if (sleepAtOrBelow < 0) { // ignore negative numbers sleepAtOrBelow = 0; } this.sleepAtOrBelow = sleepAtOrBelow; } /** * Check rate limit. * * @param record * the record * @param count * the count * @return true, if successful * @throws InterruptedException * the interrupted exception */ @Override protected boolean checkRateLimit(GHRateLimit.Record record, long count) throws InterruptedException { if (record.getRemaining() <= sleepAtOrBelow) { return sleepUntilReset(record); } return false; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy