File Coverage

lib/IPC/SRLock/Base.pm
Criterion Covered Total %
statement 54 54 100.0
branch 5 6 100.0
condition 7 9 100.0
subroutine 13 13 100.0
pod 1 1 100.0
total 80 83 100.0


line stmt bran cond sub pod time code
1             package IPC::SRLock::Base;
2              
3 1     1   481 use namespace::autoclean;
  1         2  
  1         4  
4              
5 1     1   420 use Date::Format qw( time2str );
  1         5110  
  1         77  
6 1     1   6 use English qw( -no_match_vars );
  1         2  
  1         9  
7 1         8 use File::DataClass::Types qw( Bool LoadableClass NonEmptySimpleStr
8 1     1   504 Num Object PositiveInt );
  1         2  
9 1     1   792 use IPC::SRLock::Utils qw( Unspecified hash_from merge_attributes throw );
  1         2  
  1         4  
10 1     1   708 use Time::Elapsed qw( elapsed );
  1         2528  
  1         4  
11 1     1   571 use Time::HiRes qw( usleep );
  1         997  
  1         3  
12 1     1   124 use Moo;
  1         1  
  1         6  
13              
14             # Public attributes
15             has 'debug' => is => 'ro', isa => Bool, default => 0;
16              
17             has 'log' => is => 'lazy', isa => Object,
18 5     5   553 builder => sub { $_[ 0 ]->_null_class->new };
19              
20             has 'name' => is => 'ro', isa => NonEmptySimpleStr, required => 1;
21              
22             has 'nap_time' => is => 'ro', isa => Num, default => 0.1;
23              
24             has 'patience' => is => 'ro', isa => PositiveInt, default => 0;
25              
26             has 'time_out' => is => 'ro', isa => PositiveInt, default => 300;
27              
28             # Private attributes
29             has '_null_class' => is => 'lazy', isa => LoadableClass,
30             default => 'Class::Null', init_arg => undef;
31              
32             # Construction
33             around 'BUILDARGS' => sub {
34             my ($orig, $self, @args) = @_; my $attr = $orig->( $self, @args );
35              
36             my $builder = $attr->{builder} or return $attr;
37              
38             merge_attributes $attr, $builder, [ 'debug', 'log' ];
39              
40             return $attr;
41             };
42              
43             # Private methods
44             sub _get_args {
45 15     15   17 my $self = shift; my $args = hash_from @_;
  15         30  
46              
47 15 100       32 $args->{k} or throw Unspecified, [ 'key' ]; $args->{k} .= q();
  14         21  
48 14   66     58 $args->{p} //= $PID; # uncoverable condition false
49 14   66     55 $args->{t} //= $self->time_out; # uncoverable condition false
50              
51 14         30 return $args;
52             }
53              
54             sub _sleep_or_timeout {
55 3     3   3168 my ($self, $start, $now, $key) = @_;
56              
57 3 100 100     24 $self->patience and $now > $start + $self->patience
58             and throw 'Lock [_1] timed out', [ $key ];
59 2         200277 usleep( 1_000_000 * $self->nap_time );
60 2         49 return 1;
61             }
62              
63             sub _timeout_error {
64 1     1   12 my ($self, $key, $pid, $when, $after) = @_;
65              
66 1         5 return "Timed out ${key} set by ${pid} on "
67             . time2str( '%Y-%m-%d at %H:%M', $when )." after ${after} seconds\n";
68             }
69              
70             # Public methods
71             sub get_table {
72 4     4 1 443 my $self = shift;
73 4         5 my $count = 0;
74 4         34 my $data = { align => { id => 'left',
75             pid => 'right',
76             stime => 'right',
77             tleft => 'right'},
78             count => $count,
79             fields => [ qw( id pid stime tleft ) ],
80             hclass => { id => 'most' },
81             labels => { id => 'Key',
82             pid => 'PID',
83             stime => 'Lock Time',
84             tleft => 'Time Left' },
85             values => [] };
86              
87 4         5 for my $lock (@{ $self->list }) {
  4         9  
88 2         4 my $fields = {};
89              
90 2         3 $fields->{id } = $lock->{key};
91 2         4 $fields->{pid } = $lock->{pid};
92 2         5 $fields->{stime} = time2str( '%Y-%m-%d %H:%M:%S', $lock->{stime} );
93              
94 2         205 my $tleft = $lock->{stime} + $lock->{timeout} - time;
95              
96             # uncoverable branch false
97 2 50       12 $fields->{tleft} = $tleft > 0 ? elapsed( $tleft ) : 'Expired';
98 2         846 push @{ $data->{values} }, $fields; $count++;
  2         4  
  2         3  
99             }
100              
101 4         7 $data->{count} = $count;
102 4         17 return $data;
103             }
104              
105             1;
106              
107             __END__
108              
109             =pod
110              
111             =encoding utf-8
112              
113             =head1 Name
114              
115             IPC::SRLock::Base - Common lock object attributes and methods
116              
117             =head1 Synopsis
118              
119             package IPC::SRLock::<some_new_mechanism>;
120              
121             use Moo;
122              
123             extents 'IPC::SRLock::Base';
124              
125             =head1 Description
126              
127             This is the base class for the factory subclasses of L<IPC::SRLock>. The
128             factory subclasses all inherit from this class
129              
130             =head1 Configuration and Environment
131              
132             Defines the following attributes;
133              
134             =over 3
135              
136             =item C<debug>
137              
138             Turns on debug output. Defaults to 0
139              
140             =item C<exception_class>
141              
142             Class used to throw exceptions
143              
144             =item C<log>
145              
146             If set to a log object, it's C<debug> method is called if debugging is
147             turned on. Defaults to L<Class::Null>
148              
149             =item C<name>
150              
151             Used as the lock file names. Defaults to C<ipc_srlock>
152              
153             =item C<nap_time>
154              
155             How long to wait between polls of the lock table. Defaults to 0.5 seconds
156              
157             =item C<patience>
158              
159             Time in seconds to wait for a lock before giving up. If set to 0 waits
160             forever. Defaults to 0
161              
162             =item C<pid>
163              
164             The process id doing the locking. Defaults to this processes id
165              
166             =item C<time_out>
167              
168             Time in seconds before a lock is deemed to have expired. Defaults to 300
169              
170             =back
171              
172             =head1 Subroutines/Methods
173              
174             =head2 C<BUILDARGS>
175              
176             Extract L</debug> and L</log> attribute values from the C<builder> object
177             if one was supplied
178              
179             =head2 C<get_table>
180              
181             my $data = $lock_obj->get_table;
182              
183             Returns a hash ref that contains the current lock table contents. The
184             keys/values in the hash are suitable for passing to
185             L<HTML::FormWidgets>
186              
187             =head2 C<list>
188              
189             my $array_ref = $lock_obj->list;
190              
191             Returns an array of hash refs that represent the current lock table
192              
193             =head2 C<reset>
194              
195             $lock_obj->reset( k => 'some_resource_key', ... );
196              
197             Resets the lock referenced by the C<k> attribute.
198              
199             =head2 C<set>
200              
201             $lock_obj->set( k => 'some_resource_key', ... );
202              
203             Sets the specified lock. Attributes are;
204              
205             =over 3
206              
207             =item C<k>
208              
209             Unique key to identify the lock. Mandatory no default
210              
211             =item C<p>
212              
213             Explicitly set the process id associated with the lock. Defaults to
214             the current process id
215              
216             =item C<t>
217              
218             Set the time to live for this lock. Defaults to five minutes. Setting
219             it to zero makes the lock last indefinitely
220              
221             =back
222              
223             =head2 _get_args
224              
225             Default arguments for the C<set> method
226              
227             =head2 _sleep_or_timeout
228              
229             Sleep for a bit or throw a timeout exception
230              
231             =head2 _timeout_error
232              
233             Return the text of the the timeout message
234              
235             =head1 Diagnostics
236              
237             None
238              
239             =head1 Dependencies
240              
241             =over 3
242              
243             =item L<Class::Null>
244              
245             =item L<Class::Usul>
246              
247             =item L<Date::Format>
248              
249             =item L<File::DataClass>
250              
251             =item L<Moo>
252              
253             =item L<Time::Elapsed>
254              
255             =back
256              
257             =head1 Incompatibilities
258              
259             There are no known incompatibilities in this module
260              
261             =head1 Bugs and Limitations
262              
263             There are no known bugs in this module.
264             Please report problems to the address below.
265             Patches are welcome
266              
267             =head1 Acknowledgements
268              
269             Larry Wall - For the Perl programming language
270              
271             =head1 Author
272              
273             Peter Flanigan, C<< <pjfl@cpan.org> >>
274              
275             =head1 License and Copyright
276              
277             Copyright (c) 2016 Peter Flanigan. All rights reserved
278              
279             This program is free software; you can redistribute it and/or modify it
280             under the same terms as Perl itself. See L<perlartistic>
281              
282             This program is distributed in the hope that it will be useful,
283             but WITHOUT WARRANTY; without even the implied warranty of
284             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
285              
286             =cut
287              
288             # Local Variables:
289             # mode: perl
290             # tab-width: 3
291             # End: