【问题标题】:How to get estimated time needed to finish Celery task?如何获得完成 Celery 任务所需的估计时间?
【发布时间】:2021-05-25 10:33:57
【问题描述】:

我正在尝试获取完成 Celery 任务所需的估计时间。例如,如果用户在前端触发了任务 A(可能通过单击触发对后端的 REST API 调用的按钮),它将显示一个计时器以显示该任务还需要多长时间才能完成完成。

如果我正确阅读了 Celery 的文档,我可以获得计划任务的 ETA。但是当前刚刚执行的任务呢?

我最初的想法是将以前发生在数据库中的类似任务的执行时间存储在数据库中,并可能做一个平均值作为估计所需的时间。如果有人可以在上面的例子中分享一些经验,如果他/她这样做了,那就太好了。非常感谢!

【问题讨论】:

    标签: python rabbitmq celery fastapi


    【解决方案1】:

    方法一:使用定时装饰器

    import time
    import functools
    
    
    def timer(func):
        @functools.wraps(func)
        def _wrapper(*args, **kwargs):
            start = time.perf_counter()
            val = func(*args, **kwargs)
            end = time.perf_counter()
            elapsed_time = end - start
            task_info = {"time": elapsed_time, task_args: args, task_kwargs: kwargs}
            # do something with this task_info, i.e log or save in db to be used for analysis later
            return val
    
        return _wrapper
    
    
    @app.task(name="task1")
    @timer
    def task1(...):
      ...
    

    方法二:使用芹菜信号

    import time
    from celery.signals import task_prerun, task_postrun
    
    tasks = {}
    
    
    @task_prerun.connect
    def task_prerun_handler(task_id, task, **extras):
        """ Dispatched before a task is executed. """
        tasks[task_id] = time.perf_counter()
    
    
    @task_postrun.connect
    def task_postrun_handler(task_id, task, **extras):
        """ Dispatched after a task has been executed. """
        end = time.perf_counter()
        elapsed_time = end - tasks.pop(task_id)
        # do something with this task_info, i.e log or save in db to be used for analysis later
    

    您可以查看的资源:

    【讨论】:

    • 感谢@Rupsi 的推荐!但我猜估计时间将基于以前任务的历史运行,而不是实时估计,对吧?意思是,有没有一种方法可以让工作人员仅提供估计的完成时间,而无需基于过去的运行,而只是纯粹基于运行该特定任务所需的资源?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 2017-10-25
    相关资源
    最近更新 更多