В моем текущем приложении я использую Tornado AsyncHttpClient
для запросов к веб-сайту. Поток сложный, обработка ответов на предыдущий запрос приводит к другому запросу.
Собственно, я скачиваю статью, затем анализирую ее и скачиваю изображения с упоминанием в ней.
Что меня беспокоит, так это то, что, хотя в моем журнале я ясно вижу сообщение о том, что .fetch()
на URL-адресе фотографии был выдан, фактический HTTP-запрос не делается, как показано в Wireshark.
Я пытался возиться с max_client_count и HTTP-клиентом Curl/Simple, но бахвиор всегда один и тот же - пока все статьи не будут загружены, запросы на фотографии фактически не отправляются. Как это изменить?
обновл. какой-то псевдокод
@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)
И когда он печатает Я собираюсь загрузить эту фотографию, никакого фактического запроса не делается! Вместо этого он продолжает загружать больше статей и ставить в очередь больше фотографий, пока все статьи не будут загружены, только ТОГДА все фотографии запрашиваются в большом количестве.