2010-12-22 3 views
2

Je travaille sur un blog Django et je dois être en mesure de programmer des publications à publier ultérieurement. Céleri fonctionne très bien pour la planification initiale des publications, mais je rencontre des problèmes lorsqu'un utilisateur essaie de mettre à jour le message pour qu'il soit soit replanifié, soit annulé indéfiniment.Problème lors de la planification et de la réorganisation des messages avec Celery

Voici ce que je suis en train de faire:

def save(self, **kwargs): 
    ''' 
    Saves an event. If the event is currently scheduled to publish, 
    sets a celery task to publish the event at the selected time. 
    If there is an existing scheduled task,cancel it and reschedule it 
    if necessary. 
    ''' 
    import celery 
    this_task_id = 'publish-post-%s' % self.id 
    celery.task.control.revoke(task_id=this_task_id) 

    if self.status == self.STATUS_SCHEDULED: 
     from blog import tasks 
     tasks.publish_post.apply_async(args=[self.id], eta=self.date_published, 
       task_id=this_task_id) 
    else: 
     self.date_published = datetime.now() 

    super(Post, self).save(**kwargs) 

Le problème est, une fois une tâche Céleri ID a été répertorié comme révoqué, il reste révoqué même après que j'essayer de remettre à plus tard. Cela semble être une tâche assez commune qu'il devrait y avoir une solution facile.

+0

Pourquoi utiliser le céleri? Votre publication ne peut-elle pas contenir les champs start_publishing et stop_publising datetime? –

+0

Nous aimerions programmer des événements pour changer le statut car nous pouvons invalider le cache lors de son enregistrement. – Joshmaker

+2

Notez que 'revoke' ne fonctionne qu'avec RabbitMQ! – asksol

Répondre

2

Je ne sais pas ce que votre fichier tasks.py ressemble, mais je suppose que c'est quelque chose comme ce qui suit:

from celery.decorators import task 

@task 
def publish_post(post_id): 
    ''' Sets the status of a post to Published ''' 
    from blog.models import Post 

    Post.objects.filter(pk=post_id).update(status=Post.STATUS_PUBLISHED) 

Vous devez modifier le filtre dans la tâche de veiller à ce que l'état actuel est STATUS_SCHEDULED et que l'heure dans date_published est passée. .: par exemple

from celery.decorators import task 

@task 
def publish_post(post_id): 
    ''' Sets the status of a post to Published ''' 
    from blog.models import Post 
    from datetime import datetime 

    Post.objects.filter(
     pk=post_id, 
     date_published__lte=datetime.now(), 
     status=Post.STATUS_SCHEDULED 
    ).update(status=Post.STATUS_PUBLISHED) 

De cette façon, les utilisateurs peuvent changer le statut avant et en arrière, changer le temps, et la tâche ne sera jamais changer le statut de publier si la tâche est en cours d'exécution après la colonne date_published. Pas besoin de suivre les identifiants ou de révoquer les tâches.

+0

Pas tout à fait ce que je cherchais mais ça marche pour moi! – Joshmaker

+0

Ugh, mais malheureusement, si un utilisateur enregistre un message 100X, cela va créer 100 tâches de céleri et chacun devra faire une recherche de DB à un moment ultérieur, de nombreuses fois juste pour ne rien faire. – mlissner

Questions connexes