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

标签 python flask registration email-validation

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 一个线程

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

最佳答案

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

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

It is an asynchronous task queue/job queue based on distributed message passing.Tasks can execute asynchronously (in the background) or synchronously (wait until ready).

还有一个名为 Flask-Celery 的 Flask 扩展这使得将 celery 与 flask 集成变得容易。

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

关于python - Flask 如何在某些任务(如电子邮件发送)尚未完成之前呈现页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11070137/

相关文章:

python - 将 python float 打印为单精度 float

python - 运行 Python Web 服务器

python - 使用 Locust 对 docker-compose 应用程序进行性能测试时,连接被拒绝错误 (111)

python - 如何为 flask 和 celery 应用程序创建通用的基本docker镜像

php - 第 1 行的 MySQL 语法错误和反引号提供奇怪的解决方案

ruby-on-rails - Ruby On Rails 注册流程详细信息

php - 注册页面- PHP 错误

python - 如何访问 QTextDocument 页面

Python - 如何使用复杂目录结构的 PYTHONPATH?

python - 在 Pytorch 中,复制模型的学习参数作为同一架构的第二个模型的初始化的最有效方法是什么?