jpk236 has asked for the wisdom of the Perl Monks concerning the following question:

Monks:

I've written a script to handle the inventory of our servers. It SSH's into each machine and pulls down the information, storing it in a local db.

I'm using the ConnectTimeout=10 and BatchMode=yes SSH options to prevent the script from hanging. However, on occasion there will be a server which will not respond and which won't catch on the ConnectTimeout.

An idea I had was to use threads. One thread would be the SSH routine, and the 2nd thread would be some type of timer which would kill the first thread if it took too long.

I'd like to know if there is a better way of handling this. If not, I'll need some guidance on threads, as I've never dealt with them before in Perl.

Thanks for the help.

- Justin

Replies are listed 'Best First'.
Re: Perl Threads
by ikegami (Patriarch) on Nov 06, 2007 at 21:21 UTC

    I don't believe threads can be killed (sanely), so I'd recommend using child processes instead of threads.

    Scenario 1: The child processes interface with the database directly and don't tell the parent when they're done.
    Solution: You could use wait with a calculated timeout imposed by alarm.

    Scenario 2: The child processes let the parent know when they're done, possibly sending the data to the parent instead of interfacing with the database.
    Solution: You could use select with a calculated timeout.

      Thanks for the suggestions. I've looked into alarm, and after looking at a multitude of resources have come up with this working example:

      #!/usr/bin/perl -w use strict; my ($output); eval { local $SIG{ALRM} = sub {die "SSH timeout\n"}; alarm 15; $output = `/usr/bin/ssh -o ConnectTimeout=10 host.domain.com`; alarm 0; }; if ($@) { print "SSH timed out\n"; } else { print "SSH didn't time out\n"; }

      Are there any problems with what I'm doing here?

      - Justin

        It won't work in Windows, and don't use it in threads. Otherwise, it's fine.

Re: Perl Threads
by weismat (Friar) on Nov 06, 2007 at 22:09 UTC
    Threads come with overhead for creation - thus it is usually a bad idea to start and stop threads too frequently. I would recommend you to work with two shared queues (Thread::Queue). One queue would be the queue to the threads which try to ssh, the other queue would send data from the worker threads to the database thread. The main issue is now how to synchronize the main thread with the with these threads. Either the main threads sleeps x seconds after the queue to the worker thread is cleaned or all threads stop and the main thread polls from time to time the number of threads. As you can see it is rather complex. Let me know if you need some example code.
Re: Perl Threads
by BrowserUk (Patriarch) on Nov 07, 2007 at 02:39 UTC

    Take a look at threads Signalling and the threads->kill() function in the latest versions of threads.

    I haven't had occasion to use it yet, but it seems to be tailor-made for your application and should work everywhere threads do. Ie. even on Win32.

    Update: The limitations of this feature pointed out by tye mean that it is probably not useful for your application.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Note that the documentation notes the following:

      For instance, if the thread is stuck on an I/O call, sending it a signal will not cause the I/O call to be interrupted such that the signal is acted up[on] immediately.

      Which may make these rather useless for this specific task.

      - tye        

        Which may make these rather useless for this specific task.

        Indeed++. I had not notice that (rather important) limitation tucked away down there at the end of the section. (Did mention I hadn't had occasion to use this yet :)

        That really ought to be somewhere nearer the top, like maybe the second sentence.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.