require 'active_support/core_ext/hash' require 'faraday_middleware' require 'footrest/client' require 'paul_walker' module Bearcat class Client < Footrest::Client require 'bearcat/api_array' Dir[File.join(__dir__, 'client', '*.rb')].each do |mod| mname = File.basename(mod, '.*').camelize mname = 'GraphQL' if mname == 'GraphQl' require mod include "Bearcat::Client::#{mname}".constantize end def set_connection(config) super # connection.builder.delete(Faraday::Request::Multipart) # connection.builder.insert(0, FaradayMiddleware::EncodeJson) end # Override Footrest request for ApiArray support def request(method, &block) enforce_rate_limits response = connection.send(method, &block) apply_rate_limits(response.headers['x-rate-limit-remaining']) ApiArray.process_response(response, self) 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