2010-08-10 19 views
15

UPDATE: Per facilità di lettura, qui è come aggiungere un callback prima che il reattore si spegnimento:twisted: cattura KeyboardInterrupt e lo spegnimento correttamente

reactor.addSystemEventTrigger('before', 'shutdown', callable) 

domanda iniziale segue.


Se ho un client connesso a un server, ed è agghiacciante nel ciclo principale reattore in attesa di eventi, quando ho colpito CTRL-C, ottengo una "connessione verso l'altro lato è stato perso in un non -la moda pulita: connessione persa. " Come posso configurarlo in modo che io sappia quando si verifica un KeyboardInterrupt, in modo da poter eseguire correttamente la pulizia e la disconnessione in modo pulito? O come posso implementare un modo più pulito di spegnimento che non coinvolga CTRL-C, se possibile?

+0

dolce, primo colpo su google "contorto prima dell'arresto"! – Claudiu

risposta

29

Se vuoi davvero catturare C-c in modo specifico, puoi farlo nel solito modo per un'applicazione Python - usa signal.signal per installare un gestore per SIGINT che fa tutto ciò che vuoi fare. Se invochi eventuali API Twisted dal gestore, assicurati di utilizzare reactor.callFromThread poiché quasi tutte le altre API Twisted non sono sicure per il richiamo dai gestori di segnale.

Tuttavia, se siete davvero solo interessato a inserire un po 'di pulizia del codice di arresto-tempo, allora probabilmente desidera utilizzare IService.stopService (o il meccanismo in base al quale viene implementato, reactor.addSystemEventTrigger) invece.

Se si utilizza twistd, quindi utilizzare IService.stopService è facile. Hai già un oggetto Application con almeno un servizio collegato ad esso. Puoi aggiungerne un altro con un metodo personalizzato stopService che fa funzionare il tuo arresto. Il metodo è autorizzato a restituire un valore Deferred. In tal caso, il processo di spegnimento viene sospeso fino a quando viene generato il valore Deferred. Ciò ti consente di ripulire le tue connessioni in modo corretto, anche se ciò comporta più operazioni di rete (o qualsiasi altra operazione asincrona).

Se non si utilizza twistd, utilizzare direttamente reactor.addSystemEventTrigger è probabilmente più semplice. Puoi installare un prima dell'arresto del trigger che verrà chiamato nella stessa circostanza che sarebbe stato chiamato IService.stopService. Questo trigger (solo un qualsiasi oggetto callable) può anche restituire un Deferred per ritardare lo spegnimento. Questo viene fatto con una chiamata a reactor.addSystemEventTrigger('before', 'shutdown', callable) (qualche tempo prima che l'arresto venga avviato, in modo che sia già registrato ogni volta che si verifica l'arresto).

service.tac fornisce un esempio di creazione e utilizzo di un servizio personalizzato.

wxacceptance.py fornisce un esempio di utilizzo di addSystemEventTrigger e il ritardo di spegnimento di (un arbitrario) tre secondi.

Entrambi questi meccanismi forniscono la notifica ogni volta che il reattore si sta arrestando. Ciò potrebbe essere dovuto a un tasto C-c, o potrebbe essere dovuto al fatto che qualcuno ha utilizzato kill -INT ..., oppure potrebbe essere stato chiamato da qualche parte reactor.stop(). Portano tutti allo spegnimento del reattore e lo spegnimento del reattore elabora sempre i trigger degli eventi di spegnimento.

+0

+1 - Non sapevo sul ritorno dei differiti! – MattH

+0

perfetto! ha funzionato proprio come mi piaceva ora dopo mesi di brutte pulizie è finalmente bello e carino ... – Claudiu

1

Non sono sicuro che si parli di un client o di un server che hai scritto.

In ogni caso, niente di sbagliato con "CTRL-C".

Se si sta scrivendo un server come applicazione. Sottoclasse da twisted.application.service.Service e definizione startService e stopService. Mantenere un elenco di istanze di protocollo attive. Usa stopService per esaminarli e chiuderli con grazia.

Se hai un cliente, si potrebbe anche sottoclasse Service, ma potrebbe essere più semplice da usare reactor.addSystemEventTrigger('before','shutdown',myCleanUpFunction), e stretta connessione (s) con grazia in questa funzione.

Problemi correlati