SSH2 - Asynchronous Opens & Synchronous Commandsby 5haun (Sexton)
|on Apr 04, 2014 at 09:53 UTC||Need Help??|
5haun has asked for the
wisdom of the Perl Monks concerning the following question:
Gracious Monks, I seek your counsel.
I have been tasked with integrating SSH2 support into an existing in-house framework, and I have successfully done so using the wonderful Control::CLI module, which I have enhanced with some additional functionality. However, one of the requirements is for the initial connections to the devices to be done asynchronously, as that is the slowest part of the process. So far, I can only thread the entire communication with a device (the connection, actions, reactions, and close for a given device all within one subroutine).
Basically, the request is to have the connect() calls performed simultaneously for a given array of devices and then have the rest of the operations performed serially.
For example, connections are simultaneously created to devices A, B, and C. After waiting for all the devices to be connected, an action (which is an interaction with the remote shell) is performed on device A, which could potentially affect the state on devices B or C, so the state on those devices are then inspected. This may result in an action being performed on B or C, which in turn would require the states on the other devices to be re-inspected. If communication is lost with a device, it would need to be re-established before proceeding.
A similar solution has already been done using ithreads with Telnet. The opens are performed in child threads, but the rest of the Telnet commands occur in thread 0. I don't think I will be able to use that solution with SSH, as I'd need a way of sharing the Control::CLI (i.e. Net::SSH2) object instead of having it copied to the children (threads::shared does not appear to support the Net::SSH2/Control::CLI object). I've also read here that it may be an SSH security violation to have the parent and its child thread both access the same session. If someone knows a way to do this with ithreads, I'd love to understand how it can be done. :)
Other options under consideration are to use an event loop (POE or IO::Async) or fork a process for each device and have the parent use some sort of message queue to communicate with each child (I'd need STDIN, STDOUT, STDERR, and return codes to be communicated). Right now my best option appears to figure out a way to leverage POE::Component::Generic::Net::SSH2.
Thanks in advance for your time, wisdom, and constructive suggestions.