Как определить, сколько еще запросов может сделать мое приложение, прежде чем оно достигнет ограничения скорости API Twitter? - PullRequest
0 голосов
/ 09 сентября 2018

Мое приложение обычно отправляет запрос в API Twitter на временную шкалу пользователя (твиты пользователя).

Кроме того, я использую драгоценный камень twitter и настроил клиент Twitter, чтобы мое приложение могло выполнить запрос:

client = Twitter::REST::Client.new do |config|
  config.consumer_key        = ENV["TWITTER_CONSUMER_KEY"]
  config.consumer_secret     = ENV["TWITTER_CONSUMER_SECRET"]
  config.access_token        = ENV["TWITTER_ACCESS_TOKEN"]
  config.access_token_secret = ENV["TWITTER_ACCESS_TOKEN_SECRET"]
end

Конечная точка , к которой я делаю запрос - https://api.twitter.com/1.1/statuses/user_timeline.json - имеет ограничение скорости 900 запросов каждые 15 минут.

Если я правильно понимаю, есть 2 распространенных способа определить, достигло ли мое приложение своего предела скорости, но и то, что мне нужно:

Первый подход:

Это функция, которую я написал, которая пытается сделать запрос на твиты пользователя, и если приложение имеет ограничение скорости, оно вызовет исключение.

def get_tweets_from_TwitterAPI(twitter_handle)
  tweets = []
  begin
    tweets = CLIENT.user_timeline(twitter_handle)
  rescue Twitter::Error::TooManyRequests => error
    raise error
  end
  return tweets
end

Проблема с этим подходом состоит в том, что я хотел бы узнать, сколько еще запросов мое приложение может безопасно выполнить, прежде чем я сделаю запрос к API Twitter. Я боюсь, что у этого подхода будет мой приложение пингует API Twitter через долгое время после того, как оно достигнет предела скорости, и это откроет мое приложение для карательных действий со стороны Twitter (например, мое приложение занесено в черный список).

Второй подход Второй подход состоит в том, чтобы сделать запрос к этой конечной точке Twitter - https://api.twitter.com/1.1/application/rate_limit_status.json - который отправляет данные о том, где находится статус приложения для данного ограничения скорости.

Но, опять же, у этой конечной точки также есть собственный предел скорости (180 запросов каждые 15 минут), который не очень высок. Мое приложение взорвется за этот предел. В идеальном мире я хотел бы определить текущий статус ограничения скорости моего приложения, прежде чем я сделаю запрос к API вообще. И так:

def start_tweets_fetch
  number_of_requests_in_last_15 minutes = WHERE DO I GET THIS NUMBER FROM??
  if number_of_requests_in_last_15 minutes <= 900
    get_tweets_from_TwitterAPI(twitter_handle)
  end
end

Я представляю, что мне нужно увеличить число, которое я сохранил в своей базе данных, чтобы отслеживать запросы к API. Или есть более простой способ?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Я не могу говорить о геме, который вы используете, но способ отследить ограничения вашего запроса без необходимости дополнительного вызова конечной точки rate_limit_status - это проверка X-Rate-Limit-Remaining заголовков при каждом вызове API. Однако я не знаю, доступны ли эти данные для гема Ruby, который вы используете.

0 голосов
/ 10 сентября 2018

Редактировать

Это ответ на ответ Энди Пайпера , который, я думаю, является самым простым способом отследить оставшиеся звонки.

Предполагая, что вы используете этот драгоценный камень Twitter , похоже, что каждый ответ от драгоценного камня будет заполнять Twitter::RateLimit объект информацией из заголовков ограничения скорости, как у Энди предложил.

Вы должны иметь доступ к этой информации, например так:

tweets = CLIENT.user_timeline(twitter_handle)

remaining_calls = tweets.rate_limit.remaining

Оттуда вы можете сохранить это значение, чтобы проверить его при следующем запросе. Как вы его сохраните и проверите, зависит от вас, но остальная часть моего ответа все еще может быть полезна для этого.


Примечание: Я не пробовал этот метод раньше, но это одна из первых вещей, которую я бы попробовал в вашей ситуации, если бы не сохранял журналы запросов на постоянной основе.

Одним из способов может быть использование встроенного в Rails Cache API . Это позволит вам хранить любое значение в кеш-хранилище, которое должно быть быстрее и легче, чем база данных.

number_of_requests_in_last_15 = Rails.cache.fetch("twitter_requests", expires_in: 15.minutes) { 0 }
if number_of_requests_in_last_15 minutes <= 900
  get_tweets_from_TwitterAPI(twitter_handle)
  Rails.cache.increment("twitter_requests")
end

Давайте разберемся с этим

Rails.cache.fetch("twitter_requests", expires_in: 15.minutes) { 0 }:

  • Метод fetch в Rails.cache попытается получить значение для ключа twitter_requests.
  • Если ключ не существует, он оценивает блок и устанавливает возвращаемое значение в качестве нового значения ключа и возвращает его. В этом случае, если ключ twitter_requests не существует, новое значение ключа будет 0.
  • Опция expires_in: 15.minutes, переданная методу извлечения, говорит об автоматической очистке этого ключа (twitter_requests) каждые 15 минут.

Rails.cache.increment("twitter_requests")

  • Увеличивает значение клавиши twitter_requests на 1.

Примечания

  • По умолчанию Rails будет использовать хранилище данных в памяти. Это должно работать без проблем, но все значения, хранящиеся в кэше, будут сбрасываться при каждом перезапуске сервера rails.
  • Бэкэнд кэша настраивается и может быть изменен на другие популярные системы (например, memcache, redis), но они также должны быть запущены и доступны Rails.
  • Возможно, вы захотите увеличить кеш перед вызовом API, чтобы уменьшить вероятность истечения срока действия кеша между моментом его проверки и приращением. Увеличение ключа, который не существует, вернет nil.
...