运行Python代码的正确异步方式是什么?

11

我需要从我的纯Flask应用程序发送邮件,所以我认为最简单的方法是使用smtplib进行发送。但我必须异步地执行它 - 你不能只是在请求中插入一个3秒的延迟 - 对吧?因此,我将电子邮件添加到队列(psql表)中,并从另一个程序中发送该电子邮件,该程序读取此表并使用smtplib发送。

这个第二个程序(maildonkey)作为独立的进程运行,在独立的upstart服务中运行。

现在我需要另一个小的异步服务,我在考虑是否应编写另一个Python脚本(第三个,包括我的Flask应用程序和“maildonkey”),还是应该使用类似于Python的'multiprocess'或甚至'reads'并重写第二个程序?

(当我使用Clojure编程时,我可以使用“futures”轻松在单独的线程中运行代码,因此通常会这样做。)

2个回答

10

尝试使用Gevent
您可以为长时间任务创建Greenlet对象。
这个Greenlet是绿色线程

from gevent import monkey
monkey.patch_all()
import gevent
from gevent import Greenlet

class Task(Greenlet):
    def __init__(self, name):
        Greenlet.__init__(self)
        self.name = name    
    def _run(self):
        print "Task %s: some task..." % self.name

t1 = Task("long task")
t1.start()
# here we are waiting task
gevent.joinall([t1])

你还可以将Gevent用作Flask的服务器:

from gevent.wsgi import WSGIServer
from yourapplication import app

http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()

10

你应该考虑使用Celery。它在Web框架中广泛用于异步处理,并支持许多不同的后端,如AMQP、数据库等。


2
谢谢,但我认为这对于如此简单的事情来说有些过度了 - 我已经有一个工作系统了,并且引入新组件只会增加其复杂性 - 参见http://teddziuba.com/2011/02/the-case-against-queues.html。我对同时解决问题和简化问题很感兴趣。 - Hugo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接