2017-04-23 4 views
0

Actuellement, en utilisant une API ce taux me limite à 3000 requêtes par 10 secondes. J'ai 10 000 URL qui sont récupérées en utilisant Tornado en raison de sa nature d'E/S asynchrone.Limitation de débit Python Tornado AsyncHttpClient fetch

Comment puis-je implémenter une limite de débit pour refléter la limite de l'API?

from tornado import ioloop, httpclient 

i = 0 

def handle_request(response): 
    print(response.code) 
    global i 
    i -= 1 
    if i == 0: 
     ioloop.IOLoop.instance().stop() 

http_client = httpclient.AsyncHTTPClient() 
for url in open('urls.txt'): 
    i += 1 
    http_client.fetch(url.strip(), handle_request, method='HEAD') 
ioloop.IOLoop.instance().start() 

Répondre

1

Vous pouvez vérifier où est la valeur de i se situe dans l'intervalle de 3000 demandes. Par exemple, si i est compris entre 3000 et 6000, vous pouvez définir le délai d'attente de 10 secondes sur chaque requête jusqu'à 6000. Après 6000, doublez le délai. Etc.

http_client = AsyncHTTPClient() 

timeout = 10 
interval = 3000 

for url in open('urls.txt'): 
    i += 1 
    if i <= interval: 
     # i is less than 3000 
     # just fetch the request without any timeout 
     http_client.fetch(url.strip(), handle_request, method='GET') 
     continue # skip the rest of the loop 

    if i % interval == 1: 
     # i is now 3001, or 6001, or so on ... 
     timeout += timeout # double the timeout for next 3000 calls 

    loop = ioloop.IOLoop.current() 
    loop.call_later(timeout, callback=functools.partial(http_client.fetch, url.strip(), handle_request, method='GET')) 

Remarque: Je ne testé ce code avec un petit nombre de demandes. Il se peut que la valeur de i change parce que vous soustrayez i à handle_request. Si c'est le cas, vous devez conserver une autre variable similaire à i et effectuer une soustraction sur celle-ci.