2011-08-19 15 views
6

Sto utilizzando il Broker prospettiva di twisted per parlare tra il client e il server. Il client richiede dal server un metodo remoto 'remote_ssh'. Ciò fa sì che il server PB avvii una connessione SSH utilizzando la libreria SSH di Paramiko e recupera una configurazione da un dispositivo remoto.ritardo lato server broker twistato prospettiva

Funziona tutto bene, ma quando eseguo questa operazione per più dispositivi remoti, vedo il seguente comportamento: il client di Prospettiva Broker invierà tutte le richieste al server PB. Il server PB eseguirà quindi queste richieste una alla volta (che va bene), ma non restituirà QUALSIASI dei risultati fino a quando TUTTI non saranno completi.

Ecco il codice lato server PB rilevanti:

class RMethods(pb.Root): 

    def remote_ssh(self, aDict): 

     self.login('SSH', aDict)  # Login to remote device 
     response = self.aSSH.retrieve() # Retrieve the config 
     self.aSSH.close() 

     return response 


if __name__ == "__main__": 
    reactor.listenTCP(1885, pb.PBServerFactory(RMethods())) 
    reactor.run() 

Guardando varie informazioni a livello di sistema (TCPDump e netstat), vedo il seguente (assumere 5 chiamate del metodo remoto):

chiamata remote_ssh da PB client al server PB per i cinque dispositivi remoti avviene a circa lo stesso tempo

self.login device 1 
    self.aSSH.retrieve() device 1 
    self.aSSH.close() device 1 

    self.login device 2 
    self.aSSH.retrieve() device 2 
    self.aSSH.close() device 2 

    ... 

    self.login device 5 
    self.aSSH.retrieve() device 5 
    self.aSSH.close() device 5 

    return results for all 5 devices 

non sto capendo il motivo per cui attende di restituire il r esulta (ad es. perché aspetta fino al completamento di device5 prima che vengano restituiti i risultati per device1).

risposta

5

Ciò accade perché le risposte non possono essere inviate finché il reattore non ha la possibilità di eseguire. Se tutte e cinque le richieste arrivano all'incirca alla stessa ora, il reattore può svegliarsi una volta e notarne tutti e cinque contemporaneamente. Li invierà tutti e cinque al server PB. Il metodo remote_ssh funzionerà a uno di essi, bloccando tutto il tempo. Al termine, la risposta sarà (quasi certamente) in coda. Quindi il metodo remote_ssh servirà il successivo e quella risposta verrà accodata. E così via fino a quando tutte le richieste sono state gestite. Quindi il reattore avrà completato il dispatching del gruppo originale di 5 eventi e passerà alla prossima cosa. Quando si sposta, trova i dati pronti per essere inviati e inizia a inviarli.

In altre parole, il blocco impedisce il funzionamento del reattore, incluso l'impedimento di inviare l'output che è pronto per essere inviato.

Si potrebbe provare Twisted Conch come client SSH, che potrebbe consentire di eseguire il lavoro SSH senza bloccare, oppure provare a utilizzare il codice SSH esistente con i thread (supponendo che possa essere reso thread-safe) o più processi .

+0

Stavo per commentare potresti includere un esempio su come usare Conch quando mi sono ricordato che hai già scritto: http://as.ynchrono.us/2011/03/twisted-conch-in-60-seconds.html – stderr

+0

Anche con i thread, non vedo come posso farlo (ci ho provato). Il problema fondamentale in cui mi imbatto è che devo bloccare per aspettare che i risultati SSH ritornino, ma una volta che blocco il principale Prospettive Broker remote_method, allora blocca tutta l'esecuzione delle altre connessioni SSH usando remote_method. –

+0

Perché devi bloccare per attendere il ritorno dei risultati SSH? O evitare il blocco eseguendo il lavoro in un thread o processo separato o evitare il blocco utilizzando le API client Conch che non sono bloccanti. –