flask 如何在某些任务(如电子邮件发送)尚未完成之前渲染页面?
问题
在我们的例子中,当用户向服务器提交注册信息时,服务器会先发送一封认证邮件,然后呈现一个成功页面。但是邮件发送总是需要3~5秒,也就是说他提交注册信息后至少要3秒才能得到回复。
我们做了什么
1。信号
我们已经尝试发送一个信号并触发一个邮件发送功能来做这件事:
if approved:
# ...
send_activation_signal.send(email)
login_user(u)
return redirect(url_for('register_success'))
结果
一切正常,除了在 register_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/