异步电子邮件
如果你正在使用 Python 提供的模拟电子邮件服务器,可能没有注意到这一点,那就是发送电子邮件会大大减慢应用的速度,原因是发送电子邮件时所发生的和电子邮件服务器的网络交互。通常需要几秒钟的时间才能收到电子邮件,如果收件人的电子邮件服务器速度较慢,或者收件人有多个,则可能会更久。
我真正想要的 send_email()
函数是 异步的 。 那是什么意思? 这意味着当这个函数被调用时,发送邮件的任务被安排在后台进行,释放 send_email()
函数以立即返回,以便应用可以在发送邮件的同时继续运行。
Python 实际上有多种方式支持运行异步任务, threading
和 multiprocessing
模块都可以做到这一点。 为发送电子邮件启动一个后台线程,比开始一个全新的进程需要的资源少得多,所以我打算采用这种方法:
from threading import Thread
# ...
def send_async_email(app, msg):
with app.app_context():
mail.send(msg)
def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender=sender, recipients=recipients)
msg.body = text_body
msg.html = html_body
Thread(target=send_async_email, args=(app, msg)).start()
send_async_email
函数现在运行在后台线程中,它通过 send_email()
的最后一行中的 Thread()
类来调用。 有了这个改变,电子邮件的发送将在线程中运行,并且当进程完成时,线程将结束并自行清理。 如果你已经配置了一个真正的电子邮件服务器,当你按下密码重置请求表单上的提交按钮时,肯定会注意到访问速度的提升。
你可能预期只有 msg
参数会被发送到线程,但正如你在代码中所看到的那样,我也传入了应用实例。 使用线程时,需要牢记 Flask 的一个重要设计方面。 Flask 使用 上下文 来避免必须跨函数传递参数。 我不打算详细讨论这个问题,但是需要知道的是,有两种类型的上下文,即 应用上下文 和 请求上下文 。 在大多数情况下,这些上下文由框架自动管理,但是当应用启动自定义线程时,可能需要手动创建这些线程的上下文。
许多 Flask 插件需要应用上下文才能工作,因为这使得他们可以在不传递参数的情况下找到 Flask 应用实例。这些插件需要知道应用实例的原因是因为它们的配置存储在 app.config
对象中,这正是 Flask-Mail 的情况。 mail.send()
方法需要访问电子邮件服务器的配置值,而这必须通过访问应用属性的方式来实现。 使用 with app.app_context()
调用创建的应用上下文使得应用实例可以通过来自 Flask 的 current_app
变量来进行访问。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论