2012-04-04 14 views
11

Ich musste E-Mails von meiner einfachen Flask-App senden, also dachte ich, der einfachste Weg wäre, sie mit smtplib zu senden. Aber ich musste es asynchron tun - Sie können nicht einfach eine Verzögerung von 3 Sekunden in die Anfrage einfügen - richtig? Also füge ich die E-Mail zu einer Warteschlange (psql-Tabelle) hinzu und sende sie von einem anderen Programm, das diese Tabelle liest und smptlib benutzt.Wie kann man Python-Code asynchron ausführen?

Dieses zweite Programm (maildonkey) wird als separater Prozess in einem unabhängigen Upstart-Dienst ausgeführt.

Jetzt brauche ich noch einen dieser kleinen asynchronen Dienste, und ich denke, wenn ich ein anderes Python-Skript schreiben sollte (drittens meine Flask-App und 'maildonkey' zählen) oder sollte ich etwas wie Pythons 'multiprocess' verwenden, oder gar 'threads' und schreibe das zweite Programm neu?

(Wenn ich in Clojure wurde Programmierung, ich mit 'Futures' leicht Code in einem separaten Thread ausgeführt werden könnte, in der Regel so würde ich das tun.)

+0

Ist fett notwendig? – Blender

Antwort

9

Sie betrachten Celery verwenden sollen. Es ist sehr weit verbreitet in Web-Frameworks für asynchrone Verarbeitung und unterstützt eine Vielzahl von verschiedenen Backends wie AMQP, Datenbanken etc.

+1

Danke, aber ich denke, das wäre ein Overkill für so einfache Dinge - ich habe bereits ein funktionierendes System und die Einführung einer neuen Komponente würde nur ihre Komplexität erhöhen - siehe http://teddziuba.com/2011/2011/02/the-case-against -queues.html. Ich bin daran interessiert, es zu lösen UND gleichzeitig zu vereinfachen. – Hugo

10

Versuchen Sie Gevent.
Sie können Greenlet-Objekt für Ihre lange Aufgabe erstellen.
Dieses Greenlet ist green thread.

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]) 

Sie können auch GEVENT als server für Flask verwenden:

from gevent.wsgi import WSGIServer 
from yourapplication import app 

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