File Coverage

blib/lib/MooX/Role/RunAlone.pm
Criterion Covered Total %
statement 28 44 63.6
branch 2 14 14.2
condition 0 2 0.0
subroutine 9 9 100.0
pod 1 1 100.0
total 40 70 57.1


line stmt bran cond sub pod time code
1             package MooX::Role::RunAlone;
2              
3 1     1   746 use 5.006;
  1         3  
4 1     1   6 use strict;
  1         1  
  1         20  
5 1     1   4 use warnings;
  1         2  
  1         24  
6              
7 1     1   5 use Fcntl ':flock';
  1         2  
  1         160  
8              
9             #use Moo::Role;
10 1     1   685 use Role::Tiny;
  1         4565  
  1         5  
11              
12             our $VERSION = 'v0.0.0_01';
13              
14             my $verbose = !!$ENV{VERBOSE_RUNALONE};
15             my $retry = $ENV{RETRY_RUNALONE};
16              
17             my $data_pkg = 'main::DATA';
18              
19             my @call_info = caller(6);
20             my $pkg = $call_info[0];
21              
22             sub runalone_lock {
23 1     1   199 no strict 'refs';
  1         2  
  1         43  
24 1     1   7 no warnings; # to shut up "tell() on unopened filehandle"
  1         1  
  1         81  
25 1 50   1 1 1 if ( tell( *{$data_pkg} ) == -1 ) {
  1         8  
26              
27             # if we reach this then the __END__ tag does not exist. swap in the
28             # calling script namespace to see if the __DATA__ tag exists.
29 0         0 $data_pkg = $pkg . '::DATA';
30              
31 0 0       0 if ( ( tell( *{$data_pkg} ) == -1 ) ) {
  0         0  
32 0         0 warn "FATAL: No __DATA__ or __END__ tag found\n";
33 0         0 exit 2;
34             }
35             }
36              
37             # are we alone?
38 1     1   6 use warnings; # safe to turn these on again
  1         2  
  1         284  
39 1 50       2 if ( !flock( *{$data_pkg}, LOCK_EX | LOCK_NB ) ) {
  1         22  
40              
41             # retry if requested
42 0 0       0 if ($retry) {
43 0 0       0 warn "Retrying lock attempt ...\n" if $verbose;
44 0         0 my ( $times, $sleep ) = split ',', $retry;
45 0   0     0 $sleep ||= 1;
46 0         0 while ( $times-- ) {
47 0         0 sleep $sleep;
48              
49             # we're alone!
50 0 0       0 goto ALLOK if flock *{$data_pkg}, LOCK_EX | LOCK_NB;
  0         0  
51             }
52 0 0       0 warn "Retrying lock failed ...\n" if $verbose;
53             }
54              
55             # we're done
56 0         0 warn "FATAL: A copy of '$0' is already running\n";
57 0         0 exit 1;
58             }
59              
60             ALLOK:
61 1         4 return;
62             }
63              
64             # deferring
65             if ( $ENV{DEFER_RUNALONE} ) {
66             warn "Deferring " . __PACKAGE__ . " check for '$0'\n"
67             unless $ENV{VERBOSE_RUNALONE};
68             }
69             else {
70             __PACKAGE__->runalone_lock();
71             }
72              
73             1;
74             __END__