多个 Celery 进度条

     2023-02-24     207

关键词:

【中文标题】多个 Celery 进度条【英文标题】:Multiple Celery Progress Bars 【发布时间】:2018-03-22 02:28:58 【问题描述】:

问题

我有一个 Django 站点,它使用 Celery + RabbitMQ 作为长期运行任务的任务队列。我将结果存储在 Redis 中。我已经能够使用 Celery 的 update_state 在引导进度条中显示一项任务的进度,并通过按钮向 Redis DB 进行 ajax 发布以检索当前状态。

理想情况下,我想用自己的进度条显示 Redis 中当前正在运行或最近完成的每个任务。目前,我只能通过我的小Click Here 按钮显示当前任务的进度。

我尝试为进度条创建多个类,但老实说,我对如何执行此操作感到迷茫,似乎找不到任何关于如何执行此类操作的信息。我试图上传尽可能多的代码。任何帮助将不胜感激!

代码

urls.py

urlpatterns = [
    url(r'^poll_state$', poll_state, name="poll_state"),
    url(r'^do_task$', do_task, name="do_task"),
]

views.py

from django.shortcuts import render
import json
from celery.result import AsyncResult
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt 
def do_task(request):
    data = 'Fail'
    if request.is_ajax():
        job = add.delay()
        request.session['task_id'] = job.id
        data = job.id
    else:
        data = 'This is not an ajax request!'
    json_data = json.dumps(data)
    return HttpResponse(json_data, content_type='application/json')


@csrf_exempt
def poll_state(request):
    """ A view to report the progress to the user """
    data = 'Fail'
    if request.is_ajax():
        if 'task_id' in request.POST.keys() and request.POST['task_id']:
            task_id = request.POST['task_id']
            task = AsyncResult(task_id)
            data = task.info
        else:
            data = 'No task_id in the request'
    else:
        data = 'This is not an ajax request'

    json_data = json.dumps(data)

    return HttpResponse(json_data, content_type='application/json')

tasks.py

from __future__ import absolute_import, unicode_literals
from celery import shared_task
from celery.decorators import task
from celery import current_task
from celery.result import AsyncResult
import celery
from .celery import app
import time

#Task loops every half second to update the current state
@task(bind=True, ignore_result=True)
def add(self):
    for i in range(101):
        time.sleep(0.5)
        self.update_state(state="PROGRESS", meta='current': i, 'total': 100)

celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings


# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yodaclaw.settings')

app = Celery('myAppName')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
# This allows you in shell to not have to import yodaclaw.tasks
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

@app.task
def debug_task(self):
    print('Request: 0!r'.format(self.request))

settings.py

# Celery Settings

CELERY_BROKER_URL = 'amqp://localhost'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_TRACK_STARTED = True

base.py

% load static %
<!DOCTYPE html>
<html>
<head>
    % block title_outer %
    % endblock %

    % block meta %
        <meta charset="utf-8">
        <meta http-equiv="X-UA-COMPATIBLE" content="IE=edge">
        <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    % endblock %

    % block stylesheets %
    % endblock %

    % block javascript %
    % endblock %

    % block extra_head %
    % endblock %
</head>

<body>
% block body %
    <div class="wrapper">
        % block nav_header %
        % endblock %

        % block nav_sidebar %
        % endblock %

        % block content_wrapper %
        <div class="content-wrapper">
            % block content_header %
                <section class="content-header"> 
                </section>
            % endblock %

            % block content_outer %
            <section class="content">
                % block messages %
                % endblock %

                % block content_block_wrap %
                    % block content %% endblock %
                % endblock %
            </section>
            % endblock %
        % endblock content_wrapper %

        % block nav_footer %
        % endblock %
    </div>

<!-- The Right Sidebar -->
<aside class="control-sidebar control-sidebar-light">
  <!-- Content of the sidebar goes here -->
% if task_id %
    <h6>Task ID:  task_id </h6>
         <div class="progress">
            <div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar"
                aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
                % if task_id %  task_id  % endif %
            </div>
        </div>
% endif %
    <div id="container">
        <div id="action">
            <button id="do-task">Click here!</button>
        </div>
    </div>

<!-- Ajax Post to poll_state -->
    % if task_id %
    <script type="text/javascript">
    jQuery(document).ready(function() 
        var PollState = function(task_id) 
            jQuery.ajax(
                url: "poll_state",
                type: "POST",
                data: "task_id=" + task_id,
            ).done(function(task) 
                if (task.current) 
                    jQuery('.progress-bar').css('width': task.current + '%');
                    jQuery('.progress-bar').html(task.current + '%');
                
                else 
                    jQuery('.status').html(task);
                ;
                PollState(task_id);
            );
        
        PollState(' task_id ');
    )
    </script>
    % endif %

 <!-- Clickable button for do_task -->
    <script type="text/javascript">
        jQuery('#do-task').click( function() 
            jQuery.ajax(
                url: "do_task",
                data: ,
                success: function()
                    jQuery.ajax(
                        url: "",
                        context: document.body,
                        success: function(s, x) 
                            jQuery(this).html(s);
                        
                    );
                
            )
        );
    </script>
</aside>
<!-- The sidebar's background -->
<!-- This div must placed right after the sidebar for it to work-->
<div class="control-sidebar-bg"></div>
% endblock body %



</body>
% block extra_foot %% endblock %
</html>

【问题讨论】:

【参考方案1】:

查看celery-progress,它应该能够处理这个问题。它应该像将不同的任务 ID 放入前端并将它们与不同的 div 相关联一样简单。例如。像这样:

var progressUrl1 = "% url 'celery_progress:task_status' task_id1 %";
var progressUrl2 = "% url 'celery_progress:task_status' task_id2 %";
document.addEventListener("DOMContentLoaded", function () 
  CeleryProgressBar.initProgressBar(progressUrl1);
  CeleryProgressBar.initProgressBar(progressUrl2);
);

demo page linked from the readme 上有许多不同的进度条。

【讨论】:

我正在迭代从模型中获取的 views.py 中的任务字典,然后尝试使用它们各自的进度条对所有任务运行 for 循环。但是我看到,如果我提交了 2 个工作人员和 2 个任务,则两者都是并行执行的,但特定于任务的进度条没有更新,而是两个任务的一个进度条都在更新,从而导致进度回退。每个进度条如何与其各自的任务相关联。任何帮助将不胜感激。 所描述的答案应该做到这一点。你在使用提到的图书馆吗?如果您有特定问题,可以在 github 上报告,维护人员可能会提供帮助。

是否可以显示 django celery 任务的进度条? [复制]

】是否可以显示djangocelery任务的进度条?[复制]【英文标题】:Isitpossibletoshowprogressbarofdjangocelerytask?[duplicate]【发布时间】:2013-02-1217:22:24【问题描述】:我在djangocelery中使用数据库后端。任务信息存储在数据库中名为:celery_task... 查看详情

celery 任务的实时进度跟踪

...800:48:35【问题描述】:我有一个主要的celery任务,它启动多个子任务(数千个)执行多个操作(每个子任务相同的操作)。我想要的是,从主要的celery任务实时跟踪每个动作,每个子任务完成了多少,失败了多少。总结!主要任... 查看详情

Django Celery IntegrityError

】DjangoCeleryIntegrityError【英文标题】:【发布时间】:2021-12-2511:18:13【问题描述】:我想为我的项目创建一个进度条。我有一个班级,这个班级有一些功能。特别是其中一个需要很长时间(defdownload_all),这是我想要创建进度条... 查看详情

celery使用group或者chord如何实时更新状态进度?

...的是当前的id那么如果是group,chord这样的批量任务产生的多个任务,就有多个任务id,这样就没办法更新了,也没有办法将taskid传到前端来更新进度条了在搜索这样的解决方案后找到了一个方法.这里重新继承了chord,并在body中的... 查看详情

像在 WhatsApp 中一样加载多个图像进度条

】像在WhatsApp中一样加载多个图像进度条【英文标题】:MultipleImagesProgressBarloadingLikeinWhatsApp【发布时间】:2015-08-1711:52:27【问题描述】:我想在上传或下载图像或视频时在WhatsApp中显示多个进度条。以及完成的进度条隐藏进度条... 查看详情

用一个进度条下载多个文件 java / Android

】用一个进度条下载多个文件java/Android【英文标题】:Downloadmultiplefileswithoneprogressbarjava/Android【发布时间】:2018-06-0923:04:06【问题描述】:我在for()循环的帮助下在AsyncTask中下载多个文件。下面的代码工作正常,但每个下载的文... 查看详情

如何根据嵌套循环中的多个变量报告进度(对于进度条)?

】如何根据嵌套循环中的多个变量报告进度(对于进度条)?【英文标题】:HowcanIreportprogressbasedonmultiplevariablesinanestedloop(foraprogressbar)?【发布时间】:2017-04-2922:28:48【问题描述】:我有一个BackgroundWorker和一个ProgressBar。工作时... 查看详情

具有多个不同输入的文件上传进度条(MVC)

】具有多个不同输入的文件上传进度条(MVC)【英文标题】:FileUploadProgressBarwithMultipleandDifferentInputs(MVC)【发布时间】:2020-04-3020:49:48【问题描述】:我在互联网上搜索了这个JavaScript和jQuery模板,用于文件上传进度条,它可以100... 查看详情

使用一个进度条java/android下载多个文件(代码片段)

我在for()循环的帮助下下载AsyncTask中的多个文件。下面的代码工作正常但每个文件都有自己的单个进度条下载,我只想要一个进度条用于所有下载的文件。//ProgressDialogfordownloadingimages@OverrideprotectedDialogonCreateDialog(intid)switch(id)ca... 查看详情

iOS,Swift:串行下载多个文件并将所有文件的单个进度条显示为一个进度

】iOS,Swift:串行下载多个文件并将所有文件的单个进度条显示为一个进度【英文标题】:iOS,Swift:Downloadmultiplefileseriallyandshowingsingleprogressbarforallfileasaoneprogress【发布时间】:2020-01-2307:25:12【问题描述】:我正在使用我的ios(swift4)... 查看详情

快速在 UICollectionView 中显示多个图像上传的进度条

】快速在UICollectionView中显示多个图像上传的进度条【英文标题】:ShowingprogressbaronmultipleimageuploadinUICollectionViewinswift【发布时间】:2016-03-1712:12:34【问题描述】:我有一个使用UICollectionView设计的聊天视图。我已经成功实现了图像... 查看详情

多个时如何以编程方式访问相对布局中的文本视图或进度条?

】多个时如何以编程方式访问相对布局中的文本视图或进度条?【英文标题】:HowdoIaccessatextvieworprogressbarinrelativelayoutprogramaticallywhenmultiple?【发布时间】:2015-10-2602:37:42【问题描述】:我正在以编程方式在一个活动中创建多个相... 查看详情

动画 jQuery 进度条

...-bar/demo但是进度条不使用jquery并且教程没有告诉您如何将多个按钮链接到进度条。所以搜索后我找到了这个教程:http://www.jcode. 查看详情

vb在n个表单和自动进度条上净加载多个数据网格

】vb在n个表单和自动进度条上净加载多个数据网格【英文标题】:vbnetloadmultipledatagridatnoneformandautomaticprogressbar【发布时间】:2014-01-3114:53:17【问题描述】:我在一种形式中有2个数据网格和2个按钮..如果我点击GO!,左边的数据网... 查看详情

AsyncTask 和进度条 [重复]

...【发布时间】:2014-02-0521:14:51【问题描述】:我有发送(多个文本文件)到服务器的应用程序,每个文件发送和获取响应都会更新进度条。一旦所有文件都发送完毕,它就会被关闭。我已经通过在循环中调用发送函数成功地实现... 查看详情

绑定多个下载进度

】绑定多个下载进度【英文标题】:BindingMultipleDownloadProgress【发布时间】:2015-12-1610:20:02【问题描述】:我在ObservableCollection中有一个DownloadOperation列表,并且该变量具有Progress.TotalBytesToReceive和Progress.BytesReceived属性。当我尝试... 查看详情

并发请求中的进度条[重复]

...:2017-11-1405:48:22【问题描述】:我正在我的服务器上发出多个并发请求并且它工作正常。但我想显示所有请求的总进度。我怎样才能做到这一点?我的逻辑foriin0..5POSTRequest1MultipartformDatarequest2【问题讨论】:你尝试使用getTasksWithC 查看详情

如何更改进度条的位置 - 多处理

...主要问题......在使用requests和@时了解终端中的“如何获取多个进度条”98 查看详情