EV-Etcd

 view release on metacpan or  search on metacpan

eg/distributed_mutex.pl  view on Meta::CPAN

my $lock_ttl  = 10;                # seconds; must exceed work_time + slack

my $client = EV::Etcd->new(endpoints => ['127.0.0.1:2379'], max_retries => 5);
my ($lease_id, $lock_key, $keepalive, $work_timer, $lease_died);

# 1. Lease for the lock — if we crash, the lock auto-releases after lock_ttl
$client->lease_grant($lock_ttl, sub {
    my ($r, $err) = @_;
    die "lease_grant: $err->{message}\n" if $err;
    $lease_id = $r->{id};
    say "[$$] lease=$lease_id ttl=${lock_ttl}s";

    # 2. Refresh the lease while we work
    $keepalive = $client->lease_keepalive($lease_id, sub {
        my (undef, $kerr) = @_;
        return unless $kerr;
        # Lease died — our lock is gone. Bail out before we corrupt anything.
        $lease_died = 1;
        warn "[$$] keepalive lost ($kerr->{message}) — aborting work\n";
        graceful_exit(2);
    });

eg/leader_cron.pl  view on Meta::CPAN


my ($lease_id, $leader, $keepalive, $tick_timer);

sub fail { my $m = shift; warn "[$$] $m\n"; cleanup_and_exit(1) }

# 1. Grant an election lease
$client->lease_grant($lease_ttl, sub {
    my ($r, $err) = @_;
    fail("lease_grant: $err->{message}") if $err;
    $lease_id = $r->{id};
    say "[$$] lease granted: $lease_id (ttl=$r->{ttl}s)";

    # 2. Keep the lease alive while we run
    $keepalive = $client->lease_keepalive($lease_id, sub {
        my (undef, $kerr) = @_;
        return unless $kerr;
        # NOT_FOUND = the lease expired; we lost leadership unexpectedly
        fail("keepalive lost: $kerr->{message}");
    });

    # 3. Campaign — this blocks until we're elected



( run in 2.293 seconds using v1.01-cache-2.11-cpan-364913b4093 )