【问题标题】:Python/Django: Schedule task in realtime after every X duration (secs/mins/hours?)Python / Django:每X持续时间(秒/分钟/小时?)后实时安排任务
【发布时间】:2016-10-09 19:02:13
【问题描述】:

我想在我的 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 来执行长时间的异步和周期性任务。但是 celery 不允许选项在指定的持续时间后单次运行函数。

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

【问题讨论】:

    标签: python django multithreading django-celery


    【解决方案1】:

    Celery 可以选择在特定时间排队:

    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)
    

    【讨论】:

    • 这正是我想要的。谢谢! :)
    【解决方案2】:

    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
    

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

    虽然 countdown 是一个整数,但 eta 必须是一个日期时间对象,指定准确的日期和时间(包括毫秒精度和时区信息):

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • sched 在多线程环境中不是线程安全的。而且,我想要可以在分布式机器上执行的解决方案。 Celery 的countdown 正是我想要的。 + 我已经在我的机器上配置了 celery。但是根据问题,因为我们可以使用 sched.为你 +1。
      猜你喜欢
      • 1970-01-01
      • 2020-01-03
      • 2012-12-26
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多