EV-Etcd

 view release on metacpan or  search on metacpan

lib/EV/Etcd.pm  view on Meta::CPAN


=head1 SYNOPSIS

    use EV;
    use EV::Etcd;

    my $client = EV::Etcd->new(
        endpoints => ['127.0.0.1:2379'],
    );

    # Async put
    $client->put('/my/key', 'value', sub {
        my ($resp, $err) = @_;
        die $err->{message} if $err;
        say "Put succeeded, revision: $resp->{header}{revision}";
    });

    # Async get
    $client->get('/my/key', sub {
        my ($resp, $err) = @_;
        die $err->{message} if $err;
        say "Value: $resp->{kvs}[0]{value}";
    });

    # Watch
    $client->watch('/my/key', sub {
        my ($resp, $err) = @_;
        return warn "Watch error: $err->{message}\n" if $err;
        for my $event (@{$resp->{events}}) {
            say "Event: $event->{type} on $event->{kv}{key}";
        }
    });

    EV::run;

=head1 DESCRIPTION

EV::Etcd provides a high-performance async client for etcd v3 using native
gRPC Core C API integrated with the EV event loop.

=head1 METHODS

=head2 new

    my $client = EV::Etcd->new(%options);

Options:

=over 4

=item endpoints

ArrayRef of etcd endpoints (host:port).

=item timeout

RPC timeout in seconds. Default is 30 seconds. Minimum value is 1 second.

=item max_retries

Maximum number of reconnection attempts for streaming operations (watch,
lease_keepalive, election_observe) after a connection failure. Default is 3.
Set to 0 to disable automatic reconnection.

=item health_interval

Interval in seconds for health monitoring. Default is 0 (disabled).
When enabled, the client periodically checks the gRPC channel connectivity
state and calls the on_health_change callback when the connection state changes.

=item on_health_change

Callback called when the connection health status changes. Receives two
arguments: a boolean indicating health status (1=healthy, 0=unhealthy) and
the current endpoint string.

    my $client = EV::Etcd->new(
        endpoints => ['127.0.0.1:2379'],
        health_interval => 5,
        on_health_change => sub {
            my ($is_healthy, $endpoint) = @_;
            warn $is_healthy ? "Connected to $endpoint" : "Disconnected from $endpoint";
        },
    );

=item auth_token

Pre-set authentication token. Use this to create an authenticated client
without calling authenticate() first. Useful when you already have a valid
token from a previous session.

    my $client = EV::Etcd->new(
        endpoints => ['127.0.0.1:2379'],
        auth_token => $saved_token,
    );

=back

=head1 ERROR HANDLING

Errors are returned as hash references with the following structure:

    {
        code      => 14,              # gRPC status code (integer)
        status    => "UNAVAILABLE",   # gRPC status name (string)
        message   => "Connection refused",  # Error message
        source    => "get",           # Which operation failed
        retryable => 1,               # Whether the error is retryable
    }

The C<retryable> field indicates whether the error is transient (status codes:
UNAVAILABLE, RESOURCE_EXHAUSTED, ABORTED, DEADLINE_EXCEEDED).
Streaming operations (watch, keepalive, observe) automatically reconnect
on transient failures according to the C<max_retries> configuration.
Unary RPCs (get, put, delete, etc.) do not retry automatically; use the
C<retryable> field to implement application-level retry logic.

=head2 put

    $client->put($key, $value, $callback);
    $client->put($key, $value, \%opts, $callback);

lib/EV/Etcd.pm  view on Meta::CPAN

    }, sub {
        my ($event, $err) = @_;
        if ($err) {
            warn "Watch error: $err->{message}";
            return;
        }
        # Process events...
    });

=back

=head2 EV::Etcd::Watch Methods

=head3 cancel

    $watch->cancel($callback);

Cancel the watch. The callback receives C<($response, $error)> when
cancellation is complete. The response is an empty hash reference on success.

    $watch->cancel(sub {
        my ($resp, $err) = @_;
        if ($err) {
            warn "Cancel failed: $err->{message}";
        } else {
            print "Watch cancelled\n";
        }
    });

=head2 lease_grant

    $client->lease_grant($ttl, $callback);

Grant a lease with the specified TTL (time-to-live) in seconds.

The callback receives C<($response, $error)> where response contains:

=over 4

=item id

The lease ID.

=item ttl

The actual TTL granted by the server.

=back

=head2 lease_revoke

    $client->lease_revoke($lease_id, $callback);

Revoke a lease. All keys attached to the lease will be deleted.

=head2 lease_keepalive

    my $keepalive = $client->lease_keepalive($lease_id, $callback);
    my $keepalive = $client->lease_keepalive($lease_id, \%opts, $callback);

Keep a lease alive. Creates a bidirectional streaming connection that keeps
the lease refreshed. Returns an C<EV::Etcd::Keepalive> object that can be
used to cancel the keepalive stream:

    $keepalive->cancel(sub { my ($resp, $err) = @_; });

Options:

    auto_reconnect => 1   # auto-reconnect on failure (default: 1)

=head2 EV::Etcd::Keepalive Methods

=head3 cancel

    $keepalive->cancel($callback);

Cancel the keepalive stream. The callback receives C<($response, $error)>
when cancellation is complete. The response is an empty hash reference on
success.

=head2 lease_time_to_live

    $client->lease_time_to_live($lease_id, $callback);
    $client->lease_time_to_live($lease_id, \%opts, $callback);

Get the remaining TTL of a lease.

The callback receives C<($response, $error)> where response contains:

=over 4

=item id

The lease ID.

=item ttl

Remaining TTL in seconds. Returns -1 if the lease has expired.

=item granted_ttl

The original TTL granted when the lease was created.

=item keys

Array of keys attached to this lease (only if C<keys> option is true).

=back

Options:

=over 4

=item keys

If true, also return the list of keys attached to this lease.

=back

=head2 lease_leases

lib/EV/Etcd.pm  view on Meta::CPAN


Arguments:

=over 4

=item leader_key

The leader key hash returned from C<election_campaign>.

=item value

The new value to announce.

=item callback

Called with C<($response, $error)> when complete.

=back

Example:

    $client->election_proclaim($leader_key, "new-value", sub {
        my ($resp, $err) = @_;
        if ($err) {
            warn "Proclaim failed: $err->{message}";
        }
    });

=head2 election_resign

    $client->election_resign($leader_key, $callback);

Voluntarily give up leadership.

Arguments:

=over 4

=item leader_key

The leader key hash returned from C<election_campaign>.

=item callback

Called with C<($response, $error)> when complete.

=back

Example:

    $client->election_resign($leader_key, sub {
        my ($resp, $err) = @_;
        say "Resigned from leadership" unless $err;
    });

=head2 election_observe

    my $observe = $client->election_observe($name, $callback);
    my $observe = $client->election_observe($name, \%opts, $callback);

Observe leader changes for an election. This creates a streaming connection
that receives notifications whenever the leader changes. Returns an
C<EV::Etcd::Observe> object that can be used to cancel the observe stream:

    $observe->cancel(sub { my ($resp, $err) = @_; });

Arguments:

=over 4

=item name

The name of the election to observe.

=item callback

Called with C<($response, $error)> for each leader change.

=back

Options:

=over 4

=item auto_reconnect

If true, automatically reconnect after connection failures. Default is true.

=back

The response contains:

=over 4

=item kv

The key-value pair of the current leader.

=item header

Standard response header.

=back

Example:

    my $observe = $client->election_observe("my-election", sub {
        my ($resp, $err) = @_;
        if ($err) {
            warn "Observe error: $err->{message}";
            return;
        }
        say "Leader changed: $resp->{kv}{value}";
    });

=head2 EV::Etcd::Observe Methods

=head3 cancel

    $observe->cancel($callback);



( run in 2.103 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )