【问题标题】:Trouble scheduling and rescheduling posts with Celery无法使用 Celery 安排和重新安排帖子
【发布时间】:2010-12-22 14:48:33
【问题描述】:

我正在开发一个 Django 博客,我需要能够安排帖子以在以后发布。 Celery 非常适合最初安排帖子,但是当用户尝试更新帖子以使其重新安排或无限期取消时,我遇到了问题。

这是我想要做的:

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)

问题是,一旦 Celery 任务 ID 被列为已撤销,即使我尝试重新安排它,它仍会保持撤销状态。这似乎是一个足够常见的任务,应该有一个简单的解决方案。

【问题讨论】:

  • 为什么要用芹菜?你的帖子不能只有 start_publishing 和 stop_publishing 日期时间字段吗?
  • 我们希望安排事件来更改状态,因为我们可以在保存缓存时使其无效。
  • 请注意,revoke 仅适用于 RabbitMQ!
  • @Joshmaker 您是否找到了比以下答案更清洁的方法?我现在遇到了完全相同的问题。
  • @max 接受的解决方案(以原子/幂等方式双重检查数据库)是我发现的此类问题的最佳解决方案。最好使用主数据库作为对象正确状态的“单一事实来源”。

标签: python django celery


【解决方案1】:

我不知道您的 tasks.py 文件是什么样的,但我认为它类似于以下内容:

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)

您应该在任务中编辑过滤器以确保当前状态为 STATUS_SCHEDULED 并且 date_published 中的时间已过。例如:

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)

这样,用户可以来回更改状态,更改时间,并且如果任务在 date_published 列之后运行,则任务只会更改要发布的状态。无需跟踪 id 或撤销任务。

【讨论】:

  • 呃,但遗憾的是,如果用户将帖子保存为 100 倍,这将创建 100 个 celery 任务,并且每个任务稍后都必须进行数据库查找,很多时候只是为了什么都不做。跨度>
猜你喜欢
  • 2012-12-18
  • 2014-06-25
  • 2013-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多