Nel caso non è ovvio, Si chiama reattore perché esso reagisce attrattive. Il ciclo è come reagisce.
una riga alla volta:
while True:
Non è realtàwhile True
; è più simile a while not loop.stopped
. È possibile chiamare reactor.stop()
per interrompere il ciclo e (dopo aver eseguito una logica di spegnimento) il ciclo verrà effettivamente chiuso. Ma è raffigurato nell'esempio come while True
perché quando si scrive un programma di lunga durata (come spesso sono con Twisted) è meglio presumere che il programma sarà o crash o di correre per sempre, e che "in modo pulito in uscita" non è davvero un'opzione.
timeout = time_until_next_timed_event()
Se dovessimo estendere questo calcolo un po ', si potrebbe avere più senso:
def time_until_next_timed_event():
now = time.time()
timed_events.sort(key=lambda event: event.desired_time)
soonest_event = timed_events[0]
return soonest_event.desired_time - now
timed_events
è l'elenco degli eventi in programma con reactor.callLater
; cioè le funzioni che l'applicazione ha richiesto a Twisted di funzionare in un determinato momento.
Questa riga qui è la parte "magica" di Twisted. Non riesco ad espandere wait_for_events
in modo generale, perché la sua implementazione dipende esattamente da come il sistema operativo rende disponibili gli eventi desiderati. E, dato che i sistemi operativi sono animali complessi e ingannevoli, non posso espanderlo in un modo specifico pur mantenendo abbastanza semplice la risposta alla tua domanda.
Ciò che questa funzione intende dire è, chiedere al sistema operativo, o un wrapper Python attorno ad esso, di bloccare, finché uno o più degli oggetti precedentemente registrati con esso - come minimo, roba come le porte di ascolto e stabilito le connessioni, ma anche possibilmente cose come i pulsanti su cui è possibile fare clic, è "pronto per il lavoro". Il lavoro potrebbe essere la lettura di alcuni byte da un socket quando arrivano dalla rete. Il lavoro potrebbe scrivere byte sulla rete quando un buffer si svuota sufficientemente per farlo. Potrebbe accettare una nuova connessione o eliminarne una chiusa. Ognuno di questi possibili eventi sono funzioni che il reattore può chiamare sugli oggetti: dataReceived
, buildProtocol
, resumeProducing
, ecc., Che verrà illustrato se si passa attraverso il tutorial completo di Twisted.
Una volta che abbiamo la nostra lista di ipotetici oggetti "evento", ognuno dei quali ha un immaginario "process
" metodo (i nomi esatti dei metodi sono diversi nel reattore solo a causa di incidenti della storia), quindi tornare a trattare con il tempo:
events += timed_events_until(now())
in primo luogo, questo è supponendo events
è semplicemente un list
di un abstract Event
classe, che ha un metodo process
che ogni tipo specifico di evento deve compilare.
A questo punto, il ciclo si è "riattivato", perché wait_for_events
, ha interrotto il blocco. Tuttavia, non sappiamo quanti eventi temporali potremmo aver bisogno di eseguire in base a per quanto tempo è "addormentato" per. Potremmo aver dormito per il timeout completo se non si stava verificando, ma se molte connessioni fossero attive, avremmo potuto dormire per davvero in pochissimo tempo. Quindi controlliamo l'ora corrente ("now()
"), e aggiungiamo alla lista di eventi che dobbiamo elaborare, ogni evento a tempo con un desired_time
che si trova o prima del tempo presente.
Infine,
for event in events:
event.process()
Questo significa solo che ritorto passa attraverso l'elenco delle cose che ha a che fare e lo fa. In realtà, naturalmente, gestisce le eccezioni attorno a ciascun evento e l'implementazione concreta del reattore spesso chiama direttamente in un gestore di eventi piuttosto che creare un oggetto simile a Event
per registrare il lavoro che deve essere eseguito per primo, ma concettualmente questo è solo che succede. event.process
qui potrebbe significare chiamare socket.recv()
e quindi yourProtocol.dataReceived
con il risultato, ad esempio.
Spero che questa spiegazione estesa ti aiuti a capirlo. Se desideri saperne di più su Twisted lavorando su di esso, ti incoraggio a join the mailing list, sali sul canale IRC, #twisted
per parlare delle applicazioni o #twisted-dev
per lavorare su Twisted stesso, sia su Freenode.