AnyEvent-Consul-Exec

 view release on metacpan or  search on metacpan

lib/AnyEvent/Consul/Exec.pm  view on Meta::CPAN

      cb => sub {
      $self->{_c}->kv->delete(
        "_rexec/$self->{_sid}",
        recurse => 1,
        $self->{dc_args}->@*,
        cb => sub {
          delete $self->{_sid};
          delete $self->{_c};
          $cb->();
        },
      );
    });
  }
  else {
    delete $self->{_sid};
    delete $self->{_c};
    $cb->();
  }
}

sub start {
  my ($self) = @_;
  $self->{_c} = AnyEvent::Consul->new($self->{consul_args}->@*, error_cb => sub {
    my ($err) = @_;
    $self->_cleanup(sub { $self->{on_error}->($err) });
  });
  $self->_start_session;
  return;
}

1;

=pod

=encoding UTF-8

=for markdown [![Build Status](https://secure.travis-ci.org/robn/AnyEvent-Consul-Exec.png)](http://travis-ci.org/robn/AnyEvent-Consul-Exec)

=head1 NAME

AnyEvent::Consul::Exec - Execute a remote command across a Consul cluster

=head1 SYNOPSIS

    use AnyEvent;
    use AnyEvent::Consul::Exec;
    
    my $cv = AE::cv;
    
    my $e = AnyEvent::Consul::Exec->new(
        
        # command to run
        command => 'uptime',

        # number of seconds target will wait for command, without sending
        # output, before terminating it
        wait => 2,
        
        # called once job is submitted to Consul
        on_submit => sub {
            say "job submitted";
        },
        
        # called as each target node starts to process the job
        # multiple calls, once per node
        on_ack => sub {
            my ($node) = @_;
            say "$node: ack";
        },
        
        # called when a node has output from the job
        # can be called zero or more times per node, as more output
        # becomes available
        on_output => sub {
            my ($node, $output) = @_;
            say "$node: output:";
            say "$node> $_" for split("\n", $output);
        },
        
        # called when the node completes a job
        # multiple calls, one per node
        on_exit => sub {
            my ($node, $rc) = @_;
            say "$node: exit: $rc";
        },
        
        # called once all nodes have reported completion
        # object is unusable past this point
        on_done => sub {
            say "job done";
            $cv->send;
        },
        
        # called if an error occurs anywhere during processing (not command errors)
        # typically called if Consul is unable to service requests
        # object is unusable past this point
        on_error => sub {
            my ($err) = @_;
            say "error: $err";
            $cv->send;
        },
    );
    
    # begin execution
    $e->start;

    $cv->recv;

=head1 DESCRIPTION

AnyEvent::Consul::Exec is an interface to Consul's "exec" agent function. This
is the same thing you get when you run L<consul exec|https://www.consul.io/docs/commands/exec.html>.

C<consul exec> is great, but its output is text-based, making it awkward to
parse to determine what happened on each node that ran the command.
C<AnyEvent::Consul::Exec> replaces the client portion with a library you can
use to get info about what is happening on each node as it happens.

As the name implies, it expects to be run inside an L<AnyEvent> event loop.

=head1 BASICS

Start off by instantiating a C<AnyEvent::Consul::Exec> object with the command
you want to run:

    my $e = AnyEvent::Consul::Exec->new(
        command => 'uptime',
    );

Then call C<start> to kick it off:

    $e->start;

As the C<AnyEvent> event loop progresses, the command will be executed on
remote nodes. Output and results of that command on each node will be posted to
callbacks you can optionally provide to the constructor.

When calling the constructor, you can include the C<consul_args> option with an
arrayref as a value. Anything in that arrayref will be passed as-is to the
C<AnyEvent::Consul> constructor. Use this to set the various client options
documented in L<AnyEvent::Consul> and L<Consul>.

The C<wait> option will tell the target agent how long to wait, without
receiving output, before killing the command. This does the same thing as the
C<-wait> option to C<consul exec>.

The C<node>, C<service> and C<tag> each take basic regexes that will be used to
match nodes to run the command on. See the corresponding options to C<consul exec>
for more info.

If you specify <min_node_count>, at *least* this many nodes must report in
before we consider a job done. Without this, some nodes might report back
results before we've seen an ack from the others, and your job may prematurely
be canceled on those other nodes, or your on_done callback will be called
prematurely. This is most useful if C<node> is a regex that matches an
explicit amount of nodes, for example:

    node => /^(host1|host2|host3)$/,
    min_node_count => 3,



( run in 0.497 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )