烧瓶如何在某些任务(如电子邮件发送)尚未完成之前呈现页面

Posted

技术标签:

【中文标题】烧瓶如何在某些任务(如电子邮件发送)尚未完成之前呈现页面【英文标题】:How can flask render a page before some task(like email sending) has not finished 【发布时间】:2012-06-19 16:08:27 【问题描述】:

flask 如何在某些任务(如发送电子邮件)尚未完成之前渲染页面?

问题

在我们的例子中,当用户向服务器提交注册信息时,服务器会先发送一封认证邮件,然后呈现一个成功页面。但是邮件发送总是需要3~5秒,也就是说他提交注册信息后至少需要3秒才能得到回复。

我们做了什么

1。信号

我们已经尝试发送一个信号并触发一个邮件发送功能来做这件事:

if approved:
    # ...

    send_activation_signal.send(email)

    login_user(u)
    return redirect(url_for('register_success'))

结果

一切正常,除了在 r​​egister_success 页面呈现之前至少需要 3 秒。

2。分叉一个线程

fork 一个线程来完成邮件发送

t = threading.Thread(target = send_activation, args = (email, username, email_confirm_code, ))
t.start()

结果

但看起来请求上下文的处理方式不正确。

> Exception in thread Thread-2: Traceback (most recent call last):  
> File
> "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",
> line 552, in __bootstrap_inner
>     self.run()   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",
> line 505, in run
>     self.__target(*self.__args, **self.__kwargs)   File "/Users/arthasshih/flask/happyvs/main_app/views/user.py", line 267, in
> send_activation
>     app.logger.debug("sending #############")   File "/Users/arthasshih/virtual_evns/normal/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/local.py",
> line 336, in __getattr__
>     return getattr(self._get_current_object(), name)   File "/Users/arthasshih/virtual_evns/normal/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/local.py",
> line 295, in _get_current_object
>     return self.__local()   File "/Users/arthasshih/virtual_evns/normal/lib/python2.7/site-packages/Flask-0.8-py2.7.egg/flask/globals.py",
> line 19, in _lookup_object
>     raise RuntimeError('working outside of request context') RuntimeError: working outside of request context

【问题讨论】:

发送电子邮件不需要放在单独的线程或任务引擎中。如果花了那么长时间,您的邮件服务器的配置就有问题。 @ThiefMaster 你说得对,是我的服务器到邮件服务器的连接问题。 【参考方案1】:

我在烧瓶中设置电子邮件发送时也遇到了这个问题,但问题不是烧瓶。如果你想让flask在完成发送邮件任务之前返回,这个过程必须异步运行,但它在这里是同步运行的,所以这就是等待的原因。

解决方案是使用Celery: Distributed Task Queue。这段文字来自他们的主页:

它是一个基于分布式消息传递的异步任务队列/作业队列。任务可以异步(在后台)或同步(等到准备好)执行。

还有一个名为 Flask-Celery 的 Flask 扩展,它可以轻松地将 celery 与 flask 集成。

简单地将邮件发送任务添加到 celery 的异步任务队列和渲染页面。如果任务失败,您必须确保 celery 生成一些错误日志,否则无论是否发送邮件,您都不会。

【讨论】:

仅供参考,flask-celery 已被弃用。不要使用它!您可以轻松地直接使用 celery,而无需该扩展名:“SINCE CELERY 3.0 不再需要”

以上是关于烧瓶如何在某些任务(如电子邮件发送)尚未完成之前呈现页面的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 项目中运行日常任务/脚本?

烧瓶中写入数据库的后台任务

如何停止Sharepoint发送已完成和已删除任务的任务逾期电子邮件

烧瓶邮件属性错误:“功能”对象没有属性“发送”

如何使用任务命中在 azure 批处理节点中运行的烧瓶应用程序?

关闭尚未完成 AcceptEx 的套接字 - 如果以及如何?