Domanda

Sto cercando di capire come posso fare il mio codice più asincrono utilizzando contorto.

  • Una funzione restituisce un oggetto differito
  • poi aggiungo un elenco di callback
  • il primo callback verrà chiamata dopo la funzione differita fornisce qualche risultato attraverso deferred_obj.callback
  • poi, nella catena di callback, il primo callback farà qualcosa con i dati e chiamare il secondo callback
  • ed ecc

callback tuttavia concatenati non sarà considerato asincrona perché sono incatenati e il ciclo degli eventi si continua a sparare ognuno di essi contemporaneamente fino a quando non c'è più, giusto?

Tuttavia, se ho un oggetto differita, e attribuisco come callback deferred_obj.callback come in d.addCallback(deferred_obj.callback) allora questo sarà considerato asincrono, perché il deferred_obj è in attesa per i dati, e quindi il metodo che passerà i dati è in attesa di dati e, tuttavia, una volta ho d.callback 'd' oggetto elabora i dati allora chiamare deferred_obj.callback tuttavia dal momento che questo oggetto è differita, a differenza del caso di callback incatenati, si eseguirà in modo asincrono ... giusto?

Supponendo che tutto il mio codice è non bloccante, questo significa che incatenati callback non sono asincrone mentre deferreds incatenati sono, giusto?

È stato utile?

Soluzione

I callback sono (per default) sincrono. Tuttavia, come punti il ??doc ritorto out:

Se avete bisogno di uno differita di aspettare un altro, tutto quello che dovete fare è restituire un differita da un metodo aggiunto al addCallbacks.

Così si può usarlo per fare un po 'l'elaborazione asincrona nella vostra catena di callback. Facciamo che:

from twisted.internet import reactor, defer

def callback_func_2(result, previous_data):
    # here we pass the result of the deferred down the callback chain
    # (done synchronously)
    print "calling function 1 on result:%s with previous result:%s" % (result, previous_data)
    return result

def callback_func(result):
    #let's do some asynchronous stuff in this callback
    # simple trick here is to return a deferred from a callback 
    # instead of the result itself.
    # 
    # so we can do asynchronous stuff here, 
    # like firing something 1 second later and have 
    # another method processing the result
    print "calling function 1 on result:%s" % result
    d = defer.Deferred()
    reactor.callLater(1, d.callback, "second callback")
    d.addCallback(callback_func_2, result)
    return d

def do():
    d = defer.Deferred()
    reactor.callLater(1, d.callback, "first callback")
    d.addCallback(callback_func)
    return d

do()
reactor.run()

Altri suggerimenti

Un po ', ma non v'è alcuna concorrenza in questo tipo di elaborazione degli eventi. Nessun nuovo callback verrà chiamata fino a quando il codice torna al ciclo di eventi. Così la catena di callback è sincrona. E 'asincrono solo nel ciclo di eventi.

Questo è un avvertimento di questo tipo di programmazione, i gestori più eseguire in modo rapido, e tornare al ciclo di eventi ASAP. Non dovrebbe fare qualsiasi compito che richiede tempo in un gestore.

Utilizzo di una differita non rendere il codice asincrono.

import time
from twisted.internet import defer
from twisted.internet import reactor

def blocking(duration, deferred):
    print "start blocking"
    time.sleep(duration)
    print "finished blocking"
    deferred.callback(True)

def other_task():
    print "working..."
    reactor.callLater(1, other_task)

def finish(result):
    print "stopping reactor in 2sec"
    reactor.callLater(2, reactor.stop)

def failed(reason):
    print reason
    print "stopping reactor in 2sec"
    reactor.callLater(2, reactor.stop)

def main():
    d = defer.Deferred()
    d.addCallbacks(finish, failed)
    reactor.callLater(0, blocking, 5, d)

if __name__ == "__main__":
    reactor.callLater(0, other_task)
    main()
    reactor.run()

Se si hanno a lungo-esecuzione di codice sincrono, è possibile deferToThread o suddividerla in brevi iterazioni con un Cooperatore (twisted.internet.task)

Se si vuole rendere il codice più asincrona con un approccio pulito quindi controllare questo quadro:

https://github.com/iogf/untwisted

E 'il codice ordinata, con una documentazione chiara. L'approccio a trattare con modelli asincroni è semplice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top