Domanda

Sto provando ad aggiungere un nuovo trasporto a Twisted, che leggerà i dati da uno stream - o un file in un modo tail -f , o da una pipe, ma ho dei problemi con architettura contorta.

Ho il trasporto stesso (implementa ITransport ) pronto: gestisce tutta l'apertura del file. Ho pronto funzioni / rinvii di streaming. Come lo metto insieme ora? Vorrei riportare i nuovi dati ai dataReceived () di alcuni protocolli

Potrei ovviamente creare un nuovo oggetto che imposterà i monitor I / O con callback adeguati, registrando un callback allo spegnimento del reattore (per chiudere i file / protocolli) e avviare tutto manualmente - ma è " nel modo giusto " ;? C'è qualche astrazione più bella che potrei usare? Ho visto reattor.connectWith () , ma in realtà non fornisce molta astrazione ...

Inoltre - come devo trasmettere i dati dal mio lettore al protocollo? ITransport non definisce alcuna interfaccia per esso, anche se sembra esattamente la responsabilità del trasporto.

È stato utile?

Soluzione

Sembra che tu abbia in gran parte capito come farlo. Potresti essere interessato a twisted.internet.fdesc.readFromFD , ma è lungo solo poche righe e non sta facendo nulla di particolarmente complicato (sono comunque poche righe che non devi mantenere). A parte questo - sì, in questo caso devi fare il monitoraggio I / O, perché i descrittori di file regolari non sono supportati da select / poll / epoll (vengono sempre segnalati come pronti, non quello che vuoi).

Alcuni lavori sono stati fatti sul supporto di inotify in Twisted ( http://twistedmatrix.com/trac/ticket / 972 ) ma questo non è ancora completo, quindi non ti sarà direttamente utile ora (a meno che tu non voglia aiutare a completarlo e quindi ad utilizzarlo). Supponendo che tu usi semplicemente il polling basato sul tempo, gran parte di ciò che è nel reattore non ti aiuterà molto, dal momento che quel codice è focalizzato sull'uso di un'API di prontezza fornita dal sistema (cioè, seleziona / poll / epoll) per innescare eventi .

Per il caso di pipe, tuttavia, dovresti essere in grado di utilizzare e beneficiare dei metodi di IReactorFDSet - addReader et al.

Il tuo trasporto polling basato sul tempo potrebbe comunque trarre vantaggio dall'implementazione di ITransport - anche se non sono sicuro di come implementeresti write per un tail -f -like trasporto. Beneficerai sicuramente del fatto che il tuo trasporto fornisca i dati tramite l'interfaccia IProtocol , poiché questo semplifica il riutilizzo del codice. IProtocol.dataReceived è esattamente il modo in cui vuoi trasmettere i dati dal tuo lettore (penso che sia lo stesso del tuo trasporto , vero? ). Questo non è definito su ITransport perché è un metodo che chiami su un altro oggetto che non è il trasporto.

reattor.connectWith probabilmente non ti comprerà nulla. Come dici tu, non è molto un'astrazione; Direi che è più un errore. :)

Non preoccuparti troppo di non poter aggiungere metodi direttamente al reattore. Una funzione libera che accetta un reattore come parametro è altrettanto facile da usare.

Per il callback di spegnimento, addReader dovrebbe effettivamente portarti quasi ovunque. Ogni lettore nel reattore al momento dello spegnimento avrà connectionLost richiamato (parte di IFileDescriptor ). Dovresti implementarlo per ripulire i file e il protocollo.

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