diff --git a/README.md b/README.md index e790ea4..3466c67 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,6 @@ subreddits = client.subscribed_subreddits Using RedditKit.rb at the module level allows you to use a single account without having to keep track of RedditKit::Client instances. Working at the instance method level makes it possible to use multiple accounts at once, with one client object per account. -> RedditKit.rb doesn't have any built-in rate limiting. reddit's API rules require that you make no more than 30 requests per minute and try to avoid requesting the same page more than once every 30 seconds. You can read up on the API rules [on their wiki page](https://github.com/reddit/reddit/wiki/API). - ### Authentication ```ruby diff --git a/lib/redditkit/client.rb b/lib/redditkit/client.rb index 8311ba1..9db8086 100644 --- a/lib/redditkit/client.rb +++ b/lib/redditkit/client.rb @@ -1,6 +1,7 @@ require 'faraday' require 'redditkit/error' require 'redditkit/version' +require 'redditkit/rate_limit' require 'redditkit/client/account' require 'redditkit/client/apps' require 'redditkit/client/captcha' @@ -50,6 +51,7 @@ class Client attr_accessor :authentication_endpoint attr_accessor :user_agent attr_accessor :middleware + attr_accessor :rate_limit def initialize(username = nil, password = nil) @username = username @@ -82,6 +84,10 @@ def middleware end end + def rate_limit + @rate_limit ||= RedditKit::RateLimit.new + end + private def get(path, params = nil) @@ -105,6 +111,8 @@ def delete_path(path, params = nil) end def request(method, path, parameters = {}, request_connection) + rate_limit.wait + if signed_in? request = authenticated_request_configuration(method, path, parameters) request_connection.send(method.to_sym, path, parameters, &request).env diff --git a/lib/redditkit/rate_limit.rb b/lib/redditkit/rate_limit.rb new file mode 100644 index 0000000..06cb5fc --- /dev/null +++ b/lib/redditkit/rate_limit.rb @@ -0,0 +1,19 @@ +module RedditKit + + # The class to rate-limit requests to reddit. + class RateLimit + # Time the last request was made. + attr_reader :last_request + + def initialize + @last_request = Time.at(0) + end + + # Sleep until a given number of seconds have passed since the last request + def wait(gap = 2) + wait_time = @last_request + gap - Time.now + sleep(wait_time) if wait_time > 0 + @last_request = Time.now + end + end +end