2013-06-20 3 views
3

J'ai une tâche de céleri qui ajoute des messages à une base de données comme ceci:Django est ce chaînage des tâches?

class ProcessRequests(Task): 

    def run(self, batch): 

     for e in q: 
      msg = Message.objects.create(
       recipient_number=e.mobile, 
       content=batch.content, 
       sender=e.contact_owner, 
       billee=batch.user, 
       sender_name=batch.sender_name 
      ) 
      gateway = Gateway.objects.get(pk=2) 
      msg.send(gateway) 

Puis, dans la msg.send (passerelle) modèle il y a une autre tâche qui envoie en fait le message et exécute ceci:

class SendMessage(Task): 
    name = "Sending SMS" 
    max_retries = 10 
    default_retry_delay = 3 

    def run(self, message_id, gateway_id=None, **kwargs): 
     logging.debug("About to send a message.") 


     so some stuff here 

     logging.debug("Done sending message.") 

tout cela fonctionne très bien (avec plus de 1000 messages testés), mais je l'ai lu quelque part que ensemble, mais vous ne devriez pas les tâches de la chaîne ce n'est pas enchaînez, droit? Je n'attends pas que l'un finisse avant que l'autre puisse courir.

Cet exemple est-il correct en termes de performances, etc.?

envoyer quelque chose comme ceci:

def send(self, message): 
    """ 
    Use this gateway to send a message. 

    If ``djcelery`` is installed, then we assume they have set up the 
    ``celeryd`` server, and we queue for delivery. Otherwise, we will 
    send in-process. 

    .. note:: 
     It is strongly recommended to run this out of process, 
     especially if you are sending as part of an HttpRequest, as this 
     could take ~5 seconds per message that is to be sent. 
    """ 
    if 'djcelery' in settings.INSTALLED_APPS: 
     import sms.tasks 
     sms.tasks.SendMessage.delay(message.pk, self.pk) 
    else: 
     self._send(message) 
+0

Pourriez-vous poster le code pour 'msg.send (passerelle)'? –

+0

@NicolasCortot mis à jour avec l'exemple. merci :) – Prometheus

+0

Pourquoi utilisez-vous django + db + céleri pour créer votre propre file d'attente de messages? Je vous suggère d'utiliser directement une file d'attente de messages, ou d'utiliser les fonctionnalités de mise en file d'attente de céleri. – Marcin

Répondre

5

Version courte, oui vous faites la bonne chose ici.

Version longue:

La chose est que vous ne voulez pas quelque chose comme ceci:

@task 
def something(**kwargs): 
    # do something here 
    something_else.delay().get() 

@task 
def something_else(**kwargs): 
    # do something else here 
    pass 

qui fera something attendre le résultat de something_else.

Vous pouvez même envisager de déplacer la création du message vers une tâche (de sorte que votre boucle ne génère que des tâches et ne se connecte pas immédiatement à la base de données).

PS: si vous voulez garder une trace de tous les résultats du résultat de la ProcessRequests tâche que vous pouvez exécuter ces derniers comme sous-résultats: http://docs.celeryproject.org/en/latest/userguide/canvas.html?highlight=asyncresult#subtasks

Il peut vous aider à regrouper les résultats: http://docs.celeryproject.org/en/latest/userguide/canvas.html?highlight=asyncresult#group-results

+0

merci beaucoup pour l'explication. Vraiment aide :) – Prometheus

Questions connexes