0
リクエスト間に遅延を非同期的に追加しようとしています。 私はTornado gen.sleep(x)を使用すると、私の関数(起動)が実行されません。 をから削除すると、gen.sleep(1.0)が返されますが、遅延は追加されません。 forループのリクエスト間に遅延を追加するには?私は外部APIに要求/秒を制御する必要があります。 time.sleepを使用すると、すべてのリクエストが完了すると応答が遅れます。 @ gen.engineデコレータを追加して機能を起動しようとしましたが、結果は表示されませんでした。Tornado gen.sleep add delay
コード:
import collections
import tornado.httpclient
class BacklogClient(object):
MAX_CONCURRENT_REQUESTS = 20
def __init__(self, ioloop):
self.ioloop = ioloop
self.client = tornado.httpclient.AsyncHTTPClient(max_clients=self.MAX_CONCURRENT_REQUESTS)
self.client.configure(None, defaults=dict(connect_timeout=20, request_timeout=30))
self.backlog = collections.deque()
self.concurrent_requests = 0
def __get_callback(self, function):
def wrapped(*args, **kwargs):
self.concurrent_requests -= 1
self.try_run_request()
return function(*args, **kwargs)
return wrapped
def try_run_request(self):
while self.backlog and self.concurrent_requests < self.MAX_CONCURRENT_REQUESTS:
request, callback = self.backlog.popleft()
self.client.fetch(request, callback=callback)
self.concurrent_requests += 1
def fetch(self, request, callback=None):
wrapped = self.__get_callback(callback)
self.backlog.append((request, wrapped))
self.try_run_request()
import time
from tornado import ioloop, httpclient, gen
class TornadoBacklog:
def __init__(self):
self.queue = 0
self.debug = 1
self.toProcess = [
'http://google.com',
'http://yahoo.com',
'http://nytimes.com',
'http://msn.com',
'http://cnn.com',
'http://twitter.com',
'http://facebook.com',
]
def handle_request(self, response):
print response.code
if not self.backlog.backlog and self.backlog.concurrent_requests == 0:
ioloop.IOLoop.instance().stop()
def launch(self):
self.ioloop = ioloop.IOLoop.current()
self.backlog = BacklogClient(self.ioloop)
for item in self.toProcess:
yield gen.sleep(1.0)
print item
self.backlog.fetch(
httpclient.HTTPRequest(
item,
method='GET',
headers=None,
),
self.handle_request
)
self.ioloop.start()
def main():
start_time = time.time()
scraper = TornadoBacklog()
scraper.launch()
elapsed_time = time.time() - start_time
print('Process took %f seconds processed %d items.' % (elapsed_time, len(scraper.toProcess)))
if __name__ == "__main__":
main()
参考:https://github.com/tornadoweb/tornado/issues/1400
こんにちはJesse、ありがとう、私もhandle_requestで私の停止機能を取り除いて、すべてうまくいきました。クライアントに保留中の要求があるかどうかを検出する方法はありますか?今、私はself.ioloop.start()が使用されていた場所で余分な遅延を追加しました。 – spicyramen
すべてのリクエストが完了するとすぐにループを停止するには、Tornadoのドキュメントにある同時ウェブスパイダーの例に従います。これは、あなたの正確な問題を解決しています。http://www.tornadoweb.org/en/latest/guide/queues.html –