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.


In reply to SSH2 - Asynchronous Opens & Synchronous Commands by 5haun

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.