2011-08-19 15 views
6

Estoy utilizando Twisted's Perspective Broker para hablar entre el cliente y el servidor. El cliente solicita al servidor un método remoto 'remote_ssh'. Esto hace que el servidor PB inicie una conexión SSH utilizando la biblioteca SSH de Paramiko y recupere una configuración desde un dispositivo remoto.twist perspective broker server side delay

Todo funciona bien, pero cuando lo ejecuto para varios dispositivos remotos veo el siguiente comportamiento: el cliente de Perspective Broker enviará todas las solicitudes al servidor PB. El servidor PB ejecutará estas solicitudes una a una (lo cual está bien), pero no devolverá NINGUNO de los resultados hasta que TODOS se completen.

Este es el código del lado del servidor PB relevante:

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() 

De su diversa información a nivel de sistema (TCPDump y netstat), veo el siguiente (se supone 5 llamadas del método remoto):

llamada remote_ssh de PB PB cliente a servidor para los cinco dispositivos remotos sucede más o menos al mismo tiempo

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 

yo no soy la comprensión de por qué se espera para devolver el r esultados (es decir ¿Por qué espera hasta que device5 finalice antes de que se devuelvan los resultados para device1?

Respuesta

5

Esto sucede porque las respuestas no se pueden enviar hasta que el reactor tenga la oportunidad de funcionar. Si las cinco solicitudes llegan aproximadamente al mismo tiempo, entonces el reactor puede despertarse una vez y observar las cinco al mismo tiempo. Despachará a los cinco al servidor PB. El método remote_ssh dará servicio a uno de ellos, bloqueando todo el tiempo. Cuando esté listo, la respuesta (casi con certeza) estará en cola. Luego, el método remote_ssh dará servicio al siguiente y esa respuesta se pondrá en cola. Y así sucesivamente hasta que se hayan procesado todas las solicitudes. Luego, el reactor habrá completado el despacho del grupo original de 5 eventos y pasará a lo siguiente. Cuando se mueve, encontrará datos listos para enviar y comenzar a enviarlos.

En otras palabras, el bloqueo impide que el reactor funcione, lo que incluye evitar que envíe productos listos para enviar.

Puede probar Twisted Conch como su cliente SSH, que puede permitirle hacer el trabajo SSH sin bloquearlo, o puede intentar usar su código SSH existente con hilos (suponiendo que puede hacerse seguro para subprocesos) o múltiples procesos .

+0

Iba a comentar que podría incluir un ejemplo sobre cómo usar Conch cuando recordaba que ya había escrito: http://as.ynchrono.us/2011/03/twisted-conch-in-60-seconds.html – stderr

+0

Incluso con hilos, no veo cómo puedo hacer esto (lo he estado intentando). El problema fundamental con el que me encuentro es que tengo que bloquear para esperar a que vuelvan los resultados SSH, pero una vez que bloqueo en el Broker Perspective principal remote_method, bloquea toda la ejecución de las otras conexiones SSH usando remote_method. –

+0

¿Por qué tiene que bloquear para esperar a que vuelvan los resultados de SSH? O evite el bloqueo realizando el trabajo en un subproceso o proceso separado, o evite el bloqueo mediante el uso de las API del cliente de Conch que no son de bloqueo. –

Cuestiones relacionadas