-
Notifications
You must be signed in to change notification settings - Fork 238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rate Limiting to prevent Trello errors? #204
Comments
@mockdeep I don't think I think it should be handled case by case by the user app. |
@joneslee85 sorry, I didn't mean to suggest that there should be an arbitrary module Trello
class Client
REQUEST_MUTEX = Mutex.new
WINDOW_SIZE = 10000 # 10 seconds
MAX_REQUESTS_PER_WINDOW = 100
class << self
attr_accessor :window_start, :window_request_count
end
...
def invoke_verb(name, uri, body = nil)
REQUEST_MUTEX.synchronize do
self.class.window_start ||= Time.now
self.class.window_request_count ||= 0
if self.class.window_request_count > MAX_REQUESTS_PER_WINDOW && Time.now - self.class.window_start < WINDOW_SIZE
sleep(WINDOW_SIZE - (Time.now - self.class.window_size))
self.class.window_start = Time.now
self.class.window_request_count = 0
end
# probably more logic to keep track...
self.class.window_request_count += 1
end
# other invoke stuff
end
end
end |
I could see making this sort of functionality part of an external gem, though. There's an old throttling gem that does something similar. Maybe I'll try to build something, since I've run into this sort of problem a few times. |
@mockdeep IMHO I want to keep this gem as simple and as close to the supported API that Trello offer. Feature like this tends to be varied case by case. I 👍 if it is handled by a separate gem. I am happy to feature the link to the gem in README should users look for one. |
Sounds good. I'll work on something someday when I'm trying to put off doing something else. |
@mockdeep Have you had any success hacking deeper into this? I'm hitting the rate limit a lot as well and will solve it on the client side with a stupid and primitive thing. But since Trello's rate limits seem to be hardcoded (?), having a solution in a gem that fits everybody would be much better. Edit: I can't solve this from the client side since I don't know how many HTTP requests the Trello library will produce internally when I call the various methods. |
@psy-q I've generally resolved this with class Retryer
def initialize
@retry_count = 0
end
def call(retry_on:, retry_times: 5)
yield
rescue StandardError => ex
raise ex if @retry_count >= retry_times || !accepted_error?(ex.class, retry_on)
@retry_count += 1
sleep 0.1 * 2**@retry_count
retry
end
def accepted_error?(klass, retry_on)
retry_on.is_a?(Enumerable) ? retry_on.include?(klass) : retry_on == klass
end
end Another thing I've done is to manually cache results from Trello to minimize requerying for the same data. |
Ah, brilliant, thank you! |
Not sure when Trello started sending rate-limit stats back in the headers for responses but wouldn't this make it super easy to manage and stay within rate limits? https://developers.trello.com/docs/rate-limits . I'll work on a PR to use these headers for myself. Hopefully it will be useful to others. Update: After testing the rate-limit headers, they apparently do not work. I can exceed my limit which raises:
However the headers remain as follows:
So much for high hopes. I'll use the nested resource calls instead, but sadly I'll have to write my own calls for those unless I am just not finding that feature in |
I saw this issue, but had a slightly different suggestion to handle Trello rate limiting. It would be great if the client automatically accounted for Trello API rate limits and simply delayed requests as necessary to prevent errors. I use threading to speed up my scripts, but then I'll put in some
sleep
s to prevent hitting the rate limiting.The text was updated successfully, but these errors were encountered: