为什么Tornado中的AsyncHTTPClient不会立即发送请求?

时间:2014-12-14 13:04:58

标签: python tornado asynchttpclient

在我目前的应用程序中,我使用Tornado AsyncHttpClient向网站发出请求。 流程很复杂,处理来自先前请求的响应会导致另一个请求。

实际上,我下载了一篇文章,然后对其进行分析并下载中提到的图片

让我感到困扰的是,在我的日志中,我清楚地看到一条消息,表明照片网址上的.fetch()已经发出,没有发出实际的HTTP请求,因为 Wireshark < / p>

我尝试修改max_client_count和Curl / Simple HTTP客户端,但bahvior始终是相同的 - 直到所有文章都下载后才实际发出照片请求。怎么能改变这个?

UPD。一些伪代码

@VictorSergienko我在Linux上,所以默认情况下,我猜,使用了EPoll版本。整个系统太复杂了,但归结为:

@gen.coroutine
def fetch_and_process(self, url, callback):
  body = yield self.async_client.fetch(url)
  res = yield callback(body)
  return res

@gen.coroutine
def process_articles(self,urls):
  wait_ids=[]
  for url in urls:
     #Enqueue but don't wait for one
     IOLoop.current().add_callback(self.fetch_and_process(url, self.process_article))
     wait_ids.append(yield gen.Callback(key=url))
  #wait for all tasks to finish
  yield wait_ids

@gen.coroutine
def process_article(self,body):
   photo_url=self.extract_photo_url_from_page(body)
   do_some_stuff()
   print('I gonna download that photo '+photo_url)
   yield self.download_photo(photo_url)

@gen.coroutine
def download_photo(self, photo_url):
  body = yield self.async_client.fetch(photo_url)
  with open(self.construct_filename(photo_url)) as f:
   f.write(body)

当它打印我会下载那张照片时没有实际的要求! 相反,它会继续下载更多文章并将更多照片排入队列,直到所有文章都被下载,只有这些照片才会被批量请求

1 个答案:

答案 0 :(得分:1)

AsyncHTTPClient有一个队列,你在process_articles中立即填满(“Enqueue但不等待一个”)。在处理第一篇文章时,其照片将在所有其他文章之后的队列末尾。

如果您在process_articles中使用yield self.fetch_and_process而不是add_callback,则可以在文章及其照片之间切换,但您一次只能下载一件事。要在文章和照片之间保持平衡,同时仍然一次下载多个内容,请考虑使用toro包进行同步原语。 http://toro.readthedocs.org/en/stable/examples/web_spider_example.html中的示例与您的用例类似。