2013-04-03 3 views
9

Ich möchte eine asynchrone HTTP-POST-Anfrage mit gevent - Ich interessiere mich nicht für die Antwort, ich möchte einfach die Anfrage so schnell wie möglich ausführen. Wenn ich dies jedoch unter Verwendung von gevent.spawn versuche, wird die Anforderung nie ausgeführt. Ich weiß das, weil der Aufruf der .ready() oder .successful() Methoden auf der Greenlet, die von gevent.spawn zurückgegeben wird, immer False zurückgibt.Warum führt gevent.spawn die parametrierte Funktion erst bei einem Aufruf von Greenlet.join aus?

Allerdings hat der Greenlet begonnen, denn wenn ich glet = gevent.spawn(...) nennen, dann glet.start(), ich einen Fehler sagen AssertionError: Greenlet already started.

Die einzige Zeit, die ich bekomme glet.ready() == True ist, wenn ich glet.join() aufrufen, aber das ist eine blockierende Operation. Wie kann ich das Greenlet ausführen lassen, ohne darauf warten zu müssen, dass es vollständig ist?

Antwort

7

Da Greenlets kooperativ sind, wird Ihr neues Greenlet nicht ausgeführt, bis Sie ihm nachgeben. Rufen Sie nach dem Aufruf von spawn gevent.sleep(0) an, um nachzugeben, und Ihr Greenlet sollte laufen.

Es wird weiter ausgeführt, bis es etwas tut, das verursacht, um es zu ergeben (wie das Starten dieser http-Anforderung). Dann kann Ihr anderer Code wieder fortgesetzt werden.

EDIT:

Um Ihre Frage zu grequests, die grequests.send() doc Adresse sagt:

send(r, pool=None, stream=False) 
    Sends the request object using the specified pool. If a pool isn't 
    specified this method blocks. Pools are useful because you can specify size 
    and can hence limit concurrency 

Da Sie nicht über einen Pool angegeben haben, auf die Anforderungs-Blöcke für Ihre greenlet zu beenden. Mit anderen Worten, sobald es zurückkehrt, ist das Greenlet bereits fertiggestellt. Um die Antwort zu erhalten, siehe glt.get() des zurückgegebenen Greenlet.

+0

Ah scheint das zu funktionieren! Wenn ich jedoch die Bibliothek grequests (https://github.com/kennethreitz/grequests) benutze, erzeugt das Aufrufen von grequests.send (grequests.request ("POST", )) ein Greenlet, aber dieses Greenlet nicht Ausführen auch nach dem Aufruf von gevent.sleep(). Weißt du warum das so ist? – neptune

+1

@neptune: Siehe Update – FatalError

Verwandte Themen