| blib/lib/Etcd/Lock.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % | 
| statement | 8 | 39 | 20.5 | 
| branch | 0 | 10 | 0.0 | 
| condition | 0 | 6 | 0.0 | 
| subroutine | 3 | 9 | 33.3 | 
| pod | 3 | 4 | 75.0 | 
| total | 14 | 68 | 20.5 | 
| line | stmt | bran | cond | sub | pod | time | code | 
|---|---|---|---|---|---|---|---|
| 1 | package Etcd::Lock; | ||||||
| 2 | $Etcd::Lock::VERSION = '0.03'; | ||||||
| 3 | 3 | 3 | 170607 | use 5.012; | |||
| 3 | 30 | ||||||
| 4 | |||||||
| 5 | 3 | 3 | 1214 | use Net::Etcd; | |||
| 3 | 811455 | ||||||
| 3 | 91 | ||||||
| 6 | 3 | 3 | 1105 | use boolean; | |||
| 3 | 2818 | ||||||
| 3 | 12 | ||||||
| 7 | |||||||
| 8 | sub new { | ||||||
| 9 | 0 | 0 | 0 | my $c = shift; | |||
| 10 | 0 | my %a = @_; | |||||
| 11 | 0 | my %b; | |||||
| 12 | 0 | $b{etcd} = Net::Etcd->new( { host => $a{host} } ); | |||||
| 13 | 0 | $b{ttl} = 3600; | |||||
| 14 | 0 | foreach (qw/host key ttl/) { | |||||
| 15 | 0 | 0 | $b{$_} = $a{$_} if (exists $a{$_}); | ||||
| 16 | } | ||||||
| 17 | 0 | return bless \%b, $c; | |||||
| 18 | } | ||||||
| 19 | |||||||
| 20 | sub lock { | ||||||
| 21 | 0 | 0 | 1 | my $s = shift; | |||
| 22 | 0 | return $s->_lock_unlock(true); | |||||
| 23 | } | ||||||
| 24 | |||||||
| 25 | sub unlock { | ||||||
| 26 | 0 | 0 | 1 | my $s = shift; | |||
| 27 | 0 | return $s->_lock_unlock(false); | |||||
| 28 | } | ||||||
| 29 | |||||||
| 30 | sub ttl { | ||||||
| 31 | 0 | 0 | 1 | my $s = shift; | |||
| 32 | 0 | 0 | $s->{ttl} = shift if @_; | ||||
| 33 | 0 | return $s->{ttl}; | |||||
| 34 | } | ||||||
| 35 | |||||||
| 36 | sub _lock_unlock ( ) { | ||||||
| 37 | 0 | 0 | my $s = shift; | ||||
| 38 | 0 | my $nval = shift; | |||||
| 39 | 0 | my $k = $s->{key}; | |||||
| 40 | |||||||
| 41 | 0 | my $val = $s->{etcd}->range( { key => $k } )->get_value; | |||||
| 42 | 0 | 0 | return $val unless defined $nval; | ||||
| 43 | 0 | 0 | 0 | return false if defined $val && $val eq $nval; | |||
| 44 | 0 | my $lid = $s->_lease_id; | |||||
| 45 | 0 | 0 | if ($nval) { | ||||
| 46 | 0 | $s->{etcd}->lease( { ID => $lid, TTL => $s->{ttl} } )->grant; | |||||
| 47 | 0 | $s->{etcd}->put( { key => $k, value => $nval, lease => $lid } ); | |||||
| 48 | } | ||||||
| 49 | else { | ||||||
| 50 | 0 | $s->{etcd}->deleterange( { key => $k } ); | |||||
| 51 | 0 | $s->{etcd}->lease( { ID => $lid } )->revoke; | |||||
| 52 | } | ||||||
| 53 | 0 | return true; | |||||
| 54 | } | ||||||
| 55 | |||||||
| 56 | sub _lease_id { | ||||||
| 57 | 0 | 0 | my $s = shift; | ||||
| 58 | 0 | 0 | state $leased_id //= $$ . time; | ||||
| 59 | 0 | return $leased_id; | |||||
| 60 | } | ||||||
| 61 | |||||||
| 62 | 1; | ||||||
| 63 | |||||||
| 64 | =pod | ||||||
| 65 | |||||||
| 66 | =head1 NAME | ||||||
| 67 | |||||||
| 68 | Etcd::Lock - Lock based on etcd | ||||||
| 69 | |||||||
| 70 | =for html 
 | ||||||
| 71 | |||||||
| 72 |  | ||||||
| 73 | |||||||
| 74 |  | ||||||
| 75 |  | ||||||
| 76 | |||||||
| 77 | |||||||
| 78 | =head1 VERSION | ||||||
| 79 | |||||||
| 80 | version 0.03 | ||||||
| 81 | |||||||
| 82 | =head1 SYNOPSIS | ||||||
| 83 | |||||||
| 84 | use Etcd::Lock | ||||||
| 85 | |||||||
| 86 | my $etcdLock = Etcd::Lock->new(host => 'host.name.com', key => 'lock_key'); | ||||||
| 87 | $etcdLock->lock(); | ||||||
| 88 | ... do_something ... | ||||||
| 89 | $etcdLock->unlock(); | ||||||
| 90 | |||||||
| 91 | =head1 DESCRIPTION | ||||||
| 92 | |||||||
| 93 | Etcd::Lock is a lock based on etcd. When a key is locked, try to lock same key | ||||||
| 94 | return false. Key is unlocked automatically when ttl seconds expired. | ||||||
| 95 | |||||||
| 96 | =encoding UTF-8 | ||||||
| 97 | |||||||
| 98 | =head1 METHODS | ||||||
| 99 | |||||||
| 100 | =head2 lock() | ||||||
| 101 | |||||||
| 102 | Return true if key is unlocked. Now it's locked. | ||||||
| 103 | |||||||
| 104 | =head2 unlock() | ||||||
| 105 | |||||||
| 106 | Return true if key is locked. Now it's unlocked | ||||||
| 107 | |||||||
| 108 | =head2 ttl(new_ttl) | ||||||
| 109 | |||||||
| 110 | Set or return after how many seconds a lock is automatically removed. | ||||||
| 111 | Defaul: 3600. | ||||||
| 112 | |||||||
| 113 | =head1 BUGS/CONTRIBUTING | ||||||
| 114 | |||||||
| 115 | Please report any bugs through the web interface at L | ||||||
| 116 | |||||||
| 117 | If you want to contribute changes or otherwise involve yourself in development, feel free to fork the Git repository from | ||||||
| 118 | L | ||||||
| 119 | |||||||
| 120 | =head1 SUPPORT | ||||||
| 121 | |||||||
| 122 | You can find this documentation with the perldoc command too. | ||||||
| 123 | |||||||
| 124 | perldoc etcd-lock | ||||||
| 125 | |||||||
| 126 | =head1 AUTHOR | ||||||
| 127 | |||||||
| 128 | Emiliano Bruni | ||||||
| 129 | |||||||
| 130 | =head1 COPYRIGHT AND LICENSE | ||||||
| 131 | |||||||
| 132 | This software is copyright (c) 2022 by Emiliano Bruni. | ||||||
| 133 | |||||||
| 134 | This is free software; you can redistribute it and/or modify it under | ||||||
| 135 | the same terms as the Perl 5 programming language system itself. | ||||||
| 136 | |||||||
| 137 | =cut | ||||||
| 138 | |||||||
| 139 | __END__ |