Кравлер на tornado (AsyncHTTPClient). Можно ли проще?

Всем доброго вечера.
Переписываю шустрый кравлер с связки [curl multi & c-ares] на tornado.httpclient.AsyncHTTPClient.
Покопался в документации, наваял простенький скрипт
@tornado.gen.coroutine
def test():
    def handle_response(response):
        print 'handle %s' % response.code
    num_of_try, num_of_conn = 10000, 500
    tornado.httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient", max_clients=num_of_conn)
    http_client = tornado.httpclient.AsyncHTTPClient()
    responses = yield [http_client.fetch("http://ya.ru/", callback=handle_response) for i in xrange(num_of_try)]
if __name__ == '__main__':
    tornado.ioloop.IOLoop.current().run_sync(test)

На первый взгляд, всё работает, но возникни какая HTTPError и обработка будущего выкинет мне исключение в основном потоке, тогда как я хотел бы его видеть в обработчике. Если покопаться в коде торнады, станет видно, что это задуманное поведение (если yield обрабатывает будущее, которое выкинуло исключение, торнада его перекинет).
Долго пытался обойти такое поведение и в конечном итоге код принял следующий вид:
@tornado.gen.coroutine
def test():
    def handle_response(response):
        print 'handle %s' % response.code
    num_of_try, num_of_conn = 10000, 500
    tornado.httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient", max_clients=num_of_conn)
    http_client = tornado.httpclient.AsyncHTTPClient()
    keys = set(range(num_of_try))
    for i in keys:
        http_client.fetch("http://ya.ru/", callback=(yield tornado.gen.Callback(i)))
    while keys:
        key, res = yield yieldpoints.WaitAny(keys)
        handle_request(res)
        keys.remove(key)
if __name__ == '__main__':
    tornado.ioloop.IOLoop.current().run_sync(test)

Заместо ожидания будущего напрямую мы ждём вызова уникального колбека и сами вызываем обработчик событий.

В чём вопрос: можно ли достичь аналогичного поведения без таких жутких костылей с уникальными сетами ключей и колбеками на них?
  • Вопрос задан
  • 4446 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы