File Coverage

lib/Ubic/Daemon/PidState.pm
Criterion Covered Total %
statement 54 81 66.6
branch 15 40 37.5
condition 7 12 58.3
subroutine 14 16 87.5
pod 7 7 100.0
total 97 156 62.1


line stmt bran cond sub pod time code
1             package Ubic::Daemon::PidState;
2             $Ubic::Daemon::PidState::VERSION = '1.58_01'; # TRIAL
3 36     36   158 use strict;
  36         59  
  36         1115  
4 36     36   179 use warnings;
  36         53  
  36         1262  
5              
6             # ABSTRACT: internal object representing process info stored on disk
7              
8              
9 36     36   175 use Params::Validate qw(:all);
  36         56  
  36         7073  
10 36     36   233 use Ubic::Lockf;
  36         49  
  36         1870  
11 36     36   5400 use Ubic::AtomicFile;
  36         49  
  36         2286  
12              
13             use overload '""' => sub {
14 0     0   0 my $self = shift;
15 0         0 return $self->{dir};
16 36     36   189 };
  36         57  
  36         413  
17              
18             sub new {
19 1015     1015 1 1654 my $class = shift;
20 1015         17868 my ($dir) = validate_pos(@_, { type => SCALAR });
21 1015         6191 return bless { dir => $dir } => $class;
22             }
23              
24             sub is_empty {
25 846     846 1 5250 my ($self) = validate_pos(@_, 1);
26 846         3864 my $dir = $self->{dir};
27              
28 846 50 66     1435257 return if not -d $dir and -s $dir; # old-style pidfile
29 846 100 100     19891 return if -d $dir and -s "$dir/pid"; # non-empty new-style pidfile
30              
31 378         5448 return 1;
32             }
33              
34             sub init {
35 169     169 1 988 my ($self) = validate_pos(@_, 1);
36 169         507 my $dir = $self->{dir};
37 169 50 66     2081 if (-e $dir and not -d $dir) {
38 0         0 print "converting $dir to dir\n";
39 0 0       0 unlink $dir or die "Can't unlink $dir: $!";
40             }
41 169 100       1156 unless (-d $dir) {
42 119 50       51996 mkdir $dir or die "Can't create $dir: $!";
43             }
44              
45             }
46              
47             sub read {
48 468     468 1 3707 my ($self) = validate_pos(@_, 1);
49              
50 468         1516 my $dir = $self->{dir};
51              
52 468         576 my $content;
53             my $parse_content = sub {
54 468 50   468   6527 if ($content =~ /\A pid \s+ (\d+) \n guid \s+ (.+) (?: \n daemon \s+ (\d+) )? \Z/x) {
    0          
55             # new format
56 468         13544 return { pid => $1, guid => $2, daemon => $3, format => 'new' };
57             }
58             elsif ($content eq '') {
59             # file is empty, probably lost after reboot - we didn't sync() pidfile to disk in old versions
60 0         0 return;
61             }
62             else {
63             # We consider invalid pidfile content as the fatal, unrecoverable error.
64             # Please report all cases of invalid pidfile as critical issues.
65             #
66             # (This policy will be changed if ubic become popular enough for this to annoy enough people,
67             # but collecting bugreports about weird stuff happening is more important by now.)
68 0         0 die "invalid pidfile content in pidfile $dir";
69             }
70 468         3276 };
71 468 50       5687 if (-d $dir) {
72             # pidfile as dir
73 468         12435 my $open_success = open my $fh, '<', "$dir/pid";
74 468 50       1297 unless ($open_success) {
75 0 0   22   0 if ($!{ENOENT}) {
  22         25174  
  22         28970  
  22         14465  
76 0         0 return; # pidfile not found, daemon is not running
77             }
78             else {
79 0         0 die "Failed to open '$dir/pid': $!";
80             }
81             }
82 468         9023 $content = join '', <$fh>;
83 468         2797 return $parse_content->();
84             }
85             else {
86             # deprecated - single pidfile without dir
87 0 0 0     0 if (-f $dir and not -s $dir) {
88 0         0 return; # empty pidfile - old way to stop services
89             }
90 0 0       0 open my $fh, '<', $dir or die "Failed to open $dir: $!";
91 0         0 $content = join '', <$fh>;
92 0 0       0 if ($content =~ /\A (\d+) \Z/x) {
93             # old format
94 0         0 return { pid => $1, format => 'old' };
95             }
96             else {
97 0         0 return $parse_content->();
98             }
99             }
100             }
101              
102             sub lock {
103 410     410 1 5502 my ($self, $timeout) = validate_pos(@_, 1, { type => SCALAR, default => 0 });
104              
105 410         1842 my $dir = $self->{dir};
106 410 50       4878 if (-d $dir) {
107             # new-style pidfile
108 410         4601 return lockf("$dir/lock", { timeout => $timeout });
109             }
110             else {
111 0         0 return lockf($dir, { blocking => 0 });
112             }
113             }
114              
115             sub remove {
116 26     26 1 360 my ($self) = validate_pos(@_, 1);
117 26         126 my $dir = $self->{dir};
118              
119 26 50       514 if (-d $dir) {
120 26 100       774 if (-e "$dir/pid") {
121 5 50       625 unlink "$dir/pid" or die "Can't remove $dir/pid: $!";
122             }
123             }
124             else {
125 0 0       0 unlink $dir or die "Can't remove $dir: $!";
126             }
127             }
128              
129             sub write {
130 0     0 1 0 my $self = shift;
131 0         0 my $dir = $self->{dir};
132 0 0       0 unless (-d $dir) {
133 0         0 die "piddir $dir not initialized";
134             }
135 0         0 my $params = validate(@_, {
136             pid => 1,
137             guid => 1,
138             });
139              
140 0         0 my ($pid, $guid) = @$params{qw/ pid guid /};
141 0         0 my $self_pid = $$;
142              
143 0         0 my $content =
144             "pid $self_pid\n".
145             "guid $guid\n".
146             "daemon $pid\n";
147 0         0 Ubic::AtomicFile::store( $content => "$dir/pid" );
148             }
149              
150              
151             1;
152              
153             __END__