返回介绍

任务助手

发布于 2025-01-02 21:54:01 字数 2160 浏览 0 评论 0 收藏 0

尽管我上面使用的 example() 任务是一个简单的独立函数,但导出用户动态的函数却需要应用中具有的一些功能,例如访问数据库和发送电子邮件。 因为这将在单独的进程中运行,所以我需要初始化 Flask-SQLAlchemy 和 Flask-Mail,而 Flask-Mail 又需要 Flask 应用实例以从中获取它们的配置。 因此,我将在 app/tasks.py 模块的顶部添加 Flask 应用实例和应用上下文:

app/tasks.py :创建应用及其上下文。

from app import create_app

app = create_app()
app.app_context().push()

应用在此模块中创建,因为这是 RQ worker 要导入的唯一模块。 当使用 flask 命令时,根目录中的 microblog.py 模块创建应用实例,但 RQ worker 对此却一无所知,所以当任务函数需要它时,它需要创建自己的应用实例。 你已经在好几个地方看到了 app.app_context() 方法,推送一个上下文使应用成为“当前”的应用实例,这样一来 Flask-SQLAlchemy 等插件才可以使用 current_app.config 获取它们的配置。 没有上下文, current_app 表达式会返回一个错误。

然后我开始考虑如何在这个函数运行时报告进度。除了通过 job.meta 字典传递进度信息之外,我还想将通知推送给客户端,以便自动动态更新完成百分比。为此,我将使用我在 第二十一章 中构建的通知机制。更新将以与未读消息徽章非常类似的方式工作。当服务器渲染模板时,它将包含从 job.meta 获得的“静态”进度信息,但是一旦页面位于客户端的浏览器中,通知将使用通知来动态更新百分比。由于通知的原因,更新正在运行的任务的进度将比上一个示例中的操作稍微多一些,所以我将创建一个专用于更新进度的包装函数:

app/tasks.py :设置任务进度。

from rq import get_current_job
from app import db
from app.models import Task

# ...

def _set_task_progress(progress):
    job = get_current_job()
    if job:
        job.meta['progress'] = progress
        job.save_meta()
        task = Task.query.get(job.get_id())
        task.user.add_notification('task_progress', {'task_id': job.get_id(),
                                                     'progress': progress})
        if progress >= 100:
            task.complete = True
        db.session.commit()

导出任务可以调用 _set_task_progress() 来记录进度百分比。 该函数首先将百分比写入 job.meta 字典并将其保存到 Redis,然后从数据库加载相应的任务对象,并使用 task.user 已有的 add_notification() 方法将通知推送给请求该任务的用户。 通知将被命名为 task_progress ,并且与其关联的数据将成为具有两个条目的字典:任务标识符和进度数值。 稍后我将添加 JavaScript 代码来处理这种新的通知类型。

该函数查看进度来确认任务函数是否已完成,并在这种情况下更新数据库中任务对象的 complete 属性。 数据库提交调用确保通过 add_notification() 添加的任务和通知对象都立即保存到数据库。 我需要非常精确地设计父任务,确保不执行任何数据库更改,因为执行本调用会将父任务的更改也写入数据库。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文