Django在超时时安排任务

时间:2011-06-10 17:15:23

标签: django scheduled-tasks celery

我在数据库中的实体上设置了超时,并为其分配了一个状态(活动/已完成)。我想要的是在超时到期时将该实体的状态更改为已完成。我正在考虑使用celery来创建一个计划任务,该任务与对象创建相关联的超时,这反过来会触发django信号来通知对象已经“过期”,之后我将值设置为完成信号处理器。尽管如此,这似乎是一个开销,我认为必须有一个更直截了当的方法来做到这一点。

提前谢谢你。

2 个答案:

答案 0 :(得分:0)

不一定轻量级,但当我遇到这个问题时,我有两个解决方案。

首先,我编写了一个Django管理器,它将创建一个“待过期”对象的查询集,然后删除它们。为了使这个更轻,我在他们自己的表中保持“在事件上过期”对象与实际对象的一对一关系,并且删除这些事件他们已经做了保持那张桌子小。 “要过期”对象与被标记为“已过期”的对象之间的关系仅在取消引用ForeignKey字段时导致第二个表上的数据库命中,因此它相当轻量级。然后我会用cron(Unix的日程管理员,如果你不熟悉Unix)每隔5分钟调用一次管理电话。这对于每小时左右的超时都很好。

对于更接近秒的超时,我的解决方案是运行一个单独的服务器,通过来自Django应用程序的REST调用接收超时通知。它保留了超时何时发生的排序列表,然后调用上述管理调用。它基本上是一个自己的调度程序,由Django进程提供给它的预定事件。为了便宜,我用Node.js写了它。

这两项都奏效了。 cron工作要容易得多。

答案 1 :(得分:0)

如果状态始终处于活动状态,直到它过期并且之后总是完成,那么只有一个“完成的”日期时间字段会更简单。过去具有日期时间的所有内容都将完成,未来的所有内容都将处于活动状态。除非你的问题中没有提到一些复杂性,否则它应该提供你想要的功能,而不需要任何调度。

示例:

class TaskManager(models.Manager):
    def finished(self):
        return self.filter(finish__lte=datetime.datetime.now())

    def active(self):
        return self.filter(finish__gt=datetime.datetime.now())

class Task(models.Model):
    finish = models.DateTimeField()

    def is_finished(self):
        return self.finish <= datetime.datetime.now()
相关问题