Python / Django:每隔X个持续时间(秒/分钟/小时?)实时安排任务

时间:2016-06-09 08:29:29

标签: python django multithreading django-celery

我想在指定的持续时间内从我的Django应用程序中执行一些任务(函数)。类似的东西:

... some code
async_run_func(time_interval=15_mins)  # Async call. Code within the function 
                                       # should be executed after 15 mins.
... some more code

async_run_func将在一些自定义间隔后执行。

实现这一目标的正确方法是什么?一种方法是创建一个单独的线程并在time_duration期间休眠。但这会导致服务器上的线程太多。此外,如果重新启动gunicorn进程,状态将丢失。我希望信息能够持久化。所以,我不想采用这种方法。目前我正在使用celery执行长异步和定期任务。但芹菜不允许选择在指定的持续时间后单次运行一个函数。

如果无论如何要在分布式系统上执行它,那将是很棒的。例如,函数将从一个系统调用,但代码将在其他系统上执行(使用像RabbitMQ这样的队列对我来说很好)。否则,我也可以在同一台机器上执行它。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

芹菜可以选择在特定时间入队:

your_async_function.apply_async(args=(your, args, tuple),
                                kwargs={your: kwargs},
                                countdown=15 * 60)

或者使用子任务语法来计算所有args,然后延迟

your_async_function.s(your, args, tuple, your: kwargs).delay(countdown=15 * 60)

如果该函数没有args,您可以跳过它们直接执行

your_async_function.delay(countdown=15 * 60)

答案 1 :(得分:1)

使用sched模块怎么样?简单而有效。

import sched, time

sc = sched.scheduler(time.time, time.sleep)
sc.enter(15, 1, async_run_func, ())
sc.run

答案 2 :(得分:0)

ETA and Countdown是使用django-celery执行此操作的选项。

来自document

  

ETA(预计到达时间)可让您设置特定日期和时间,这是您执行任务的最早时间。 倒计时是将ETA设置为未来几秒的快捷方式。

     

例如:

>>> result = add.apply_async((2, 2), countdown=3)
>>> result.get()    # this takes at least 3 seconds to return
20

保证在指定的日期和时间之后的某个时间执行任务,但不一定在该确切的时间执行。截止日期中断的可能原因可能包括队列中等待的许多项目,或者网络延迟时间过长。为了确保您的任务及时执行,您应该监视队列是否拥塞。

  

倒计时是整数,eta必须是日期时间对象,指定确切的日期和时间(包括毫秒精度和时区信息):

>>> from datetime import datetime, timedelta

>>> tomorrow = datetime.utcnow() + timedelta(days=1)
>>> add.apply_async((2, 2), eta=tomorrow)