Я пытаюсь построить соединители для twitter поверх twitter4j с помощью java. Одна из проблем, с которой Twitte4j не справляется и ожидает, что вы будете иметь дело, - это проблема с ограничениями.Как создать надежное многопоточное приложение для twitter api, используя twitter4j?
Мой подход, чтобы сделать все возможное из twitter api, используя Twitter4j, - это построить несколько потоков поверх него. У меня есть твиты дамп с ничего, кроме tweet id и пользователей с идентификаторами пользователя в моей базе данных. Мне нужны мои нити twitter для запроса twitter и обновления этих таблиц всякий раз, когда в них втекает новая информация. Итак, я построил два разных потока: один, который обновляет таблицу пользователей, и тот, который обновляет таблицу твитов. Поток пользовательского обновления довольно прост в использовании, coz twitter поддерживает запросы до 100 пользователей за один раз (пользователи/поиск). Тем не менее, твитовая нить поддерживает только по одному (твиты/показ). Итак, у меня есть поток «tweet update», запустите еще 5 потоков, в которых каждый поток идет и запрашивает твиттер и обновляет по одному сообщению за раз. Это место, где ratelimit вступает в картину. Итак, в любой момент у меня есть 6 потоков и запрос на TwitterService (мой класс обслуживания). Эти потоки перед запросом всегда проверяют, пострадал ли ratelimit, если да, они переходят в спящий режим. Поэтому метод обслуживания, что потоки вызов выглядит так:
private synchronized void checkRateLimitStatus() {
if (rateLimitHit) {
try {
logger.warn("RateLimit has been reached");
wait(secondsUntilReset * 1000);
rateLimitHit = false;
secondsUntilReset = 0;
} catch (InterruptedException ie) {
ie.printStackTrace();
}
notifyAll();
}
}
Булева rateLimitHit устанавливается Twitter4J слушателем, который проверяет количество запросов остались. Когда счетчик равен нулю, для этого bool установлено значение true. Код выглядит следующим образом:
public synchronized void onRateLimitStatus(RateLimitStatusEvent evt) {
RateLimitStatus status = evt.getRateLimitStatus();
if (status.getRemainingHits() == 0) {
rateLimitHit = true;
secondsUntilReset = status.getSecondsUntilReset();
}
}
Проблема с этим, скажем, у меня есть еще 3 запросов, оставшихся в Twitter, а также метод checkRateLimitStatus() возвращает ложь для всех 6 запросов (сог это не было set, все же). Таким образом, все потоки начинаются с того, что счетчик еще не равен нулю. Но, когда первые 3 потока выполняются с помощью Twitter, счетчик достигнет нуля, а остальные три потока потерпят неудачу.
Как решить эту проблему? Как сделать эти потоки более надежными?
Вычислив локально, вы хотите сказать, что мне нужно было бы подсчитать количество запросов, сделанных локально? – Jay
Я имею в виду, что этот предел можно оценить, и алгоритм можно оптимизировать, чтобы не дойти до него, и в случае, если он достигнут, ваши потоки могут корректно обрабатывать исключения и продолжать запрашивать. –
ну ... пока, я знаю, что предел 350. Но это может измениться позже. Кроме того, количество оставшихся у меня осталось от Twitter. Поэтому, хотя я могу рассчитать его локально, это, вероятно, не очень хорошо. Представьте себе сценарий, когда моя сеть отключена, и мой поток будет запущен и обратный отсчет, однако Twitter не будет доступен. Идея здесь заключается в использовании предела твиттера, который twitter дает вам через заголовок ответа. – Jay