2017-09-03 8 views
0

Je veux interroger une API (qui prend du temps) avec beaucoup d'éléments (~ 100) mais pas tous en même temps. Au lieu de cela, je veux un peu de temps entre les requêtes.Céleri + Python: file d'attente des tâches qui demandent beaucoup de temps dans une autre tâche

Ce que j'ai actuellement est une tâche qui est exécuté de manière asynchrone et itère sur les requêtes et après chaque itération attend un certain temps:

@shared_task 
def query_api_multiple(values): 
    delay_between_queries = 1 

    query_results = [] 

    for value in values: 
     time.sleep(delay_between_queries) 

     response = query_api(value) 
     if response['result']: 
      query_results.append(response) 

    return query_results 

Ma question est, lorsque plusieurs de ces demandes arrivent, sera la deuxième la requête est exécutée après la fin du premier ou pendant que le premier est toujours en cours d'exécution? Et quand ils ne sont pas exécutés en même temps, comment puis-je y parvenir?

+1

Vous devez utiliser ETA - Planification d'une tâche pour plus tard, pour le faire de manière asynchrone en utilisant ETA (heure d'arrivée estimée) comme: later = now + timedelta (hours = 1) access_awful_system.apply_async ((object_id), eta = later) [référence] (https://fernandofreitasalves.com/using-celery-with-multiple-queues-retries-and-scheduled-tasks/) ETA. –

Répondre

1

Oui, si vous créez des tâches multiples puis ils peuvent fonctionner en même temps.

Vous pouvez évaluer la limite d'un type de tâche avec céleri si vous souhaitez limiter le nombre de tâches exécutées par période. Alternativement, vous pouvez implémenter un modèle de limitation de débit en utilisant quelque chose comme redis, combiné avec des tentatives de céleri, si vous avez besoin de plus de flexibilité que ce que celery fournit OOtB.

1

Vous ne devriez pas utiliser time.sleep mais limitons votre tâche à la place:

Task.rate_limit

Définissez la limite de vitesse pour ce type de tâche (limite le nombre de tâches qui peuvent être exécutées dans un temps donné Cadre).

Les limites de débit peuvent être spécifiées en secondes, minutes ou heures par en ajoutant "/ s", "/ m" ou "/ h" à la valeur. Les tâches seront réparties uniformément sur la période spécifiée.

Exemple: "100/m" (cent tâches par minute). Cela appliquera un délai minimum de de 600 ms entre le démarrage de deux tâches sur la même instance de travail.

Donc, si vous voulez limiter à 1 requête par seconde, essayez ceci:

@shared_task(rate_limit='1/s') 
def query_api_multiple(values): 
    ...