2016-05-06 14 views
2

Ich muss Remote-Anrufe tätigen, die ziemlich lange dauern können (über 60 Sekunden). Unser gesamter Code beruht auf der Verarbeitung des Rückgabewerts von callRemote. Das ist ziemlich schlimm, da wir die gesamte Zeit auf IO blockieren, obwohl twqisted + 50 Worker-Threads ausgeführt werden.Twisted callRemote

Wir verwenden derzeit so etwas wie

result = threads.blockingCallFromThread(reactor, callRemote, "method", args) 

und das Ergebnis erhalten/weitergehen, aber wie der Name schon sagt, es ist die Ereignisschleife ist blockiert, so dass wir nicht für mehrere Ergebnisse gleichzeitig warten.

Es gibt keine Möglichkeit, dass ich den gesamten Code umwandeln kann, um es asynchron zu machen, also denke ich, dass der einzige Weg ist, die langen IO-Aufgaben auf Threads zu verschieben.

Ich versuche, die Remote-Anrufe in Threads zu machen, aber ich kann keinen Weg finden, um das Ergebnis der blockierenden Anrufe zurück zu bekommen. Die RemoteCalls sind gemacht, das Ergebnis ist irgendwo, aber ich kann es einfach nicht verstehen.

Was ich versuche zur Zeit zu tun, sieht aus wie

reactor.callInThread(callRemote, name, *args, **kw) 

, die eine leere Latente zurück (warum?).

Ich versuche, das Ergebnis in eine Art Warteschlange zu bringen, aber es wird einfach nicht funktionieren. Wie mache ich das ?

Antwort

2

AFAIK, blockingCallFromThread führt Code in reactor 's Thread. Deshalb funktioniert es nicht so, wie Sie es brauchen.

Wenn ich Sie richtig verstehe, müssen Sie einige Operation aus reactor s Thread verschieben und das Ergebnis in reactor s Thread erhalten.

Ich verwende Ansatz mit deferToThread für den gleichen Fall. Beispiel mit deferreds:

import time 
from twisted.internet import reactor, threads 

def doLongCalculation(): 
    time.sleep(1) 
    return 3 

def printResult(x): 
    print x 

# run method in thread and get result as defer.Deferred 
d = threads.deferToThread(doLongCalculation) 
d.addCallback(printResult) 
reactor.run() 

Auch könnten Sie in threads.deferToThreadPool interessiert.

Documentation about threading in Twisted.

+1

Danke für die Antwort, aber eigentlich habe ich schon versucht, dass und ein paar andere Dinge, und ich bekomme das Ergebnis eine latente zurück (dh er druckt ‚), nicht Ich bekomme, wenn ich einen blockingCallFromThread mache. Irgendeine Idee ? Ich nehme an, es hat etwas mit verschachtelten Deferred zu tun, aber ich finde keine Möglichkeit, die inneren Deferreds zu feuern. – DenverCoder9

+0

Auch ich habe reactor.callInThread versucht, die auch nicht funktioniert, frage ich mich, was ist der Unterschied zwischen reactor.callInThread und threads.deferToThread? – DenverCoder9

+0

In Bezug auf verschachtelte Deferred, ist mein Tipp, versuchen Sie, Ihren Code mit '@ defer.inlineCallback' zu refaktorieren, wenn möglich. Ich habe gerade in die Quelle von 'blockingCallFromThread' http://twistedmatrix.com/trac/browser/tags/releases/twisted-16.0.0/twisted/internet/threads.py#L93 geschaut. Der Code verwendet 'Queue.Queue' zum Speichern der Ergebnisse von Callback und Errback. Mein zweiter Tipp: Versuchen Sie, blockingCallFromThread zu imitieren und nähern Sie sich mit "Queue", aber verwenden Sie "callInThread", um die Berechnung in einen separaten Thread zu verschieben. –