lib/bearcat/client.rb in bearcat-1.3.28 vs lib/bearcat/client.rb in bearcat-1.3.30
- old
+ new
@@ -1,6 +1,9 @@
+require 'active_support/core_ext/hash'
require 'footrest/client'
+require 'paul_walker'
+
module Bearcat
class Client < Footrest::Client
require 'bearcat/api_array'
require 'bearcat/client/file_helper'
require 'bearcat/client/assignments'
@@ -68,13 +71,66 @@
include ContentMigrations
include ContentExports
include CustomGradebookColumns
include ExternalTools
-
# Override Footrest request for ApiArray support
def request(method, &block)
- ApiArray::process_response(connection.send(method, &block), self)
+ enforce_rate_limits
+ response = connection.send(method, &block)
+ apply_rate_limits(response.headers['x-rate-limit-remaining'])
+ ApiArray.process_response(response, self)
end
- end
+ def enforce_rate_limits
+ return unless limit_remaining.present?
+ return unless limit_remaining < Bearcat.rate_limit_min
+
+ tts = ((Bearcat.rate_limit_min - limit_remaining) / 5).ceil
+ tts = Bearcat.min_sleep_seconds if tts < Bearcat.min_sleep_seconds
+ tts = Bearcat.max_sleep_seconds if tts > Bearcat.max_sleep_seconds
+
+
+ message = "Canvas API rate limit minimum #{Bearcat.rate_limit_min} reached. "\
+ "Sleeping for #{tts} second(s) to catch up ~zzZZ~. "\
+ "Limit Remaining: #{limit_remaining}"
+ Bearcat.logger.debug(message)
+
+ sleep(tts)
+ end
+
+ def apply_rate_limits(limit)
+ return if limit.nil?
+ self.limit_remaining = limit.to_i
+ end
+
+ def using_master_rate_limit?
+ config[:master_rate_limit].present? || Bearcat.master_rate_limit.present?
+ end
+
+ def limit_remaining
+ if using_master_rate_limit?
+ Bearcat.master_mutex.synchronize do
+ limit = PaulWalker::RateLimit.get(config[:token], config[:token])
+ if limit.nil?
+ PaulWalker::RateLimit.add(config[:token], config[:token], 0, Bearcat::rate_limit_min)
+ limit = { current: 0 }.with_indifferent_access
+ end
+ Bearcat.logger.debug limit['current'].to_s
+ limit['current']
+ end
+ else
+ Bearcat.rate_limits[config[:token]]
+ end
+ end
+
+ def limit_remaining=(value)
+ if using_master_rate_limit?
+ Bearcat.master_mutex.synchronize do
+ PaulWalker::RateLimit.add(config[:token], config[:token], value, Bearcat::rate_limit_min)
+ end
+ else
+ Bearcat.rate_limits[config[:token]] = value
+ end
+ end
+ end
end