Verdrehte nicht blockierende Methode - Wie?
-
26-10-2019 - |
Frage
Mein Code sieht so aus:
... # class Site(Resource)
def render_POST(self,request)
otherclass.doAssync(request.args)
print '1'
return "done" #that returns the HTTP response, always the same.
...
def doAssync(self,msg):
d = defer.Deferred()
reactor.callLater(0,self.doStuff,d,msg)
d.addCallback(self.sucess)
def doStuff(self,d,msg):
# do some stuff
time.sleep(2) #just for example
d.callback('ok')
def sucess(msg):
print msg
Die Ausgabe:
1
OK
Bisher, so gut, aber die HTTP -Antwort (zurückgegeben ') tritt erst nach der Verzögerung auf (Zeit.S -Sleep (2)). Ich kann das sagen, weil der Browser 2 Sekunden lang "laden".
Was mache ich falsch?
Lösung
Was Sie falsch machen, ist, einen Blockierungsanruf auszuführen (time.sleep(2)
), während Twisted erwartet, dass Sie nur nicht blockierende Operationen ausführen. Dinge, die nicht warten. Weil du das hast time.sleep(2)
Dort kann Twisted nichts anderes tun, während diese Funktion schläft. Es kann also auch keine Daten an den Browser senden.
Im Falle des time.sleep(2)
, Sie würden das durch einen anderen ersetzen reactor.callLater
Anruf. Angenommen, Sie haben tatsächlich für die bestimmt time.sleep(2)
Rufen Sie an, um ein anderer Blockiervorgang zu sein. Wie Sie es beheben können, hängt von der Operation ab. Wenn Sie die Operation auf nicht blockierende Weise ausführen können, tun Sie dies. Für viele solcher Operationen (wie die Datenbankinteraktion) wird bereits mit nicht blockierenden Alternativen gedreht. Wenn das, was Sie tun, keine nicht blockierende Oberfläche und Twisted hat keine Alternative dazu, müssen Sie den Code möglicherweise in einem separaten Thread ausführen (zum Beispiel verwenden Sie beispielsweise twisted.internet.threads.deferToThread
), obwohl dies erfordert, dass Ihr Code tatsächlich thread ist.