Net::SSH::Mechanize::Multi - parallel ssh invocation


version 0.1.3


    my $manager = Net::SSH::Mechanize::Multi->new(

        # Set the default parameters for the Net::SSH::Mechanize
        # instances we will create
        constructor_defaults => { login_timeout => 180 },


    # Add connection definitions as a list of connection-name to
    # Net::SSH::Mechanize instance pairs (or shorthand equivalents, as
    # illustrated).

        # This defines the connection using a
        # Net::SSH::Mechanize::ConnectParams instance (or subclass
        # thereof)
        connection1 => Net::SSH::Mechanize::ConnectParams->new(
            hostname => '',

        # This defines it using a hashref of constructor parameters
        # for Net::SSH::Mechanize
        connection2 => {
            user => 'joe',
            hostname => '',
            login_timeout => 60,
        # This passes a Net::SSH::Mechanize instance directly
        connection3 => Net::SSH::Mechanize->new(
            user => 'joe',
            hostname => '',
            login_timeout => 60,

        # ...        

    # At this point no hosts have been contacted.

    # Connect to a named subset of them all in parallel like this.
    # The callback should expect the name and the appropriate
    # Net::SSH::Mechanize instance as arguments.
    # Synchronous commands in the callback work asyncronously 
    # thanks to Coro::AnyEvent.
    my @names = qw(host1 host2);
    my $threads = $manager->in_parallel(@names => sub {
        my ($name, $ssh) = @_;

        printf "About to connect to %s using;\n'$s'\n\n",
            $name, $ssh->connection_params->ssh_cmd

        # note, the login is done implicitly when you access the
        # ->session parameter, or a method which delegates to it.

        # do stuff... 
        print "checking git status of config definition:\n";
        print $ssh->sudo_capture("cd /root/config; git status");
        # ...

    # Wait for them all to complete.
    $_->join for @$threads;

    print "done\n";

There is a full implementation of this kind of usage is in the gofer script included in this distribution.


$obj = $class->new(%params)

Creates a new instance. Parameters is a hash or a list of key-value parameters. Valid parameter keys are:


This is an optional parameter which can be used to define a hashref of default parameters to pass to Net::SSH::Mechanize instances created by this class. These defaults can be overridden in individual cases.

Currently it is also possible to pass parameters to initialise the names and ssh_instances attributes, but since the content of those are intended to be correlated this is definitely not recommended. Use ->add instead.


$hashref = $obj->constructor_defaults =head2 $obj->constructor_defaults(\%hashref)

This is an read-write accessor which allows you to specify the default parameters to pass to the Net::SSH::Mechanize constructor. These defaults can be overridden in individual cases.

$hashref = $obj->names

This is a hashref of connection names mapped to Net::SSH::Mechanize instances. It is not recommend you change this directly, use the ->add method instead.

$hashref = $obj->ssh_instances

This is an arrayref listing Net::SSH::Mechanize instances we have created, in the order they have been defined via ->add (which is also the order they will be iterated over within ->in_parallel).


@mech_instances = $obj->add(%connections)

Adds one or more named connection definitions.

%connections is a hash or list of name-value pairs defining what to connect to. The order in which they are defined here is preserved and used when iterating over them in ->in_parallel.

The names are simple string aliases, and can be anything unique (to this instance). If a duplicate is encountered, an exception will be thrown.

The values can be:

<A Net::SSH::Mechanize instance>

The instance will be used as given to connect to a host.

<A Net::SSH::Mechanize::ConnectParams instance>>

The instance will be used to create a Net::SSH::Mechanize instance to use.

A hashref of constructor paramters for Net::SSH::Mechanize >

The hashref will be passed to Net::SSH::Mechanize->new to get an instance to use.

A list of the Net::SSH::Mechanize instances are returned, in the order they were defined.

This method can be called any number of times, so long as the connection names are never duplicated.

@threads = $obj->in_parallel(@names, \&actions)

This method accepts a list of host-names, and a callback. The callback should expect two parameters: a connection name, and a Net::SSH::Mechanize instance.

It first checks that all the names have been defined in an earlier ->add invocation. If any are unknown, an exception is thrown.

Otherwise, it iterates over the names in the order given, and invokes the callback with the name and the appropriate Net::SSH::Mechanize instance.

Note: the callback is invoked each time as a co-routine. See Coro and Coro::AnyEvent for more information about this, but it essentially means that each one is asynchronously run in parallel. This method returns a list of Coro threads, immediately, before the callbacks have completed.

Your program is then free to do other things, and/or call ->join on each of the threads to wait for their termination.


Nick Stokoe <>


Copyright (c) 2011, Nick Stokoe <>. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.