使用Celery安排和重新安排帖子时遇到问题
我正在做一个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被标记为撤销,它就会一直保持撤销状态,即使我尝试重新安排它。这看起来是一个比较常见的任务,应该有简单的解决办法。
1 个回答
3
我不知道你的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或者撤销任务了。