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.60';
3 33     33   107 use strict;
  33         34  
  33         679  
4 33     33   96 use warnings;
  33         33  
  33         666  
5              
6             # ABSTRACT: internal object representing process info stored on disk
7              
8              
9 33     33   102 use Params::Validate qw(:all);
  33         33  
  33         3891  
10 33     33   126 use Ubic::Lockf;
  33         34  
  33         1079  
11 33     33   2936 use Ubic::AtomicFile;
  33         31  
  33         1344  
12              
13             use overload '""' => sub {
14 0     0   0 my $self = shift;
15 0         0 return $self->{dir};
16 33     33   115 };
  33         17  
  33         290  
17              
18             sub new {
19 879     879 1 1404 my $class = shift;
20 879         8810 my ($dir) = validate_pos(@_, { type => SCALAR });
21 879         4655 return bless { dir => $dir } => $class;
22             }
23              
24             sub is_empty {
25 729     729 1 3242 my ($self) = validate_pos(@_, 1);
26 729         2588 my $dir = $self->{dir};
27              
28 729 50 66     15680 return if not -d $dir and -s $dir; # old-style pidfile
29 729 100 100     13450 return if -d $dir and -s "$dir/pid"; # non-empty new-style pidfile
30              
31 323         3708 return 1;
32             }
33              
34             sub init {
35 150     150 1 800 my ($self) = validate_pos(@_, 1);
36 150         398 my $dir = $self->{dir};
37 150 50 66     1325 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 150 100       893 unless (-d $dir) {
42 103 50       4706 mkdir $dir or die "Can't create $dir: $!";
43             }
44              
45             }
46              
47             sub read {
48 406     406 1 2501 my ($self) = validate_pos(@_, 1);
49              
50 406         861 my $dir = $self->{dir};
51              
52 406         413 my $content;
53             my $parse_content = sub {
54 406 50   406   3768 if ($content =~ /\A pid \s+ (\d+) \n guid \s+ (.+) (?: \n daemon \s+ (\d+) )? \Z/x) {
    0          
55             # new format
56 406         9133 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 406         2280 };
71 406 50       3773 if (-d $dir) {
72             # pidfile as dir
73 406         8611 my $open_success = open my $fh, '<', "$dir/pid";
74 406 50       961 unless ($open_success) {
75 0 0   19   0 if ($!{ENOENT}) {
  19         12708  
  19         15074  
  19         6832  
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 406         5588 $content = join '', <$fh>;
83 406         1085 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 353     353 1 3290 my ($self, $timeout) = validate_pos(@_, 1, { type => SCALAR, default => 0 });
104              
105 353         1049 my $dir = $self->{dir};
106 353 50       3150 if (-d $dir) {
107             # new-style pidfile
108 353         2887 return lockf("$dir/lock", { timeout => $timeout });
109             }
110             else {
111 0         0 return lockf($dir, { blocking => 0 });
112             }
113             }
114              
115             sub remove {
116 22     22 1 176 my ($self) = validate_pos(@_, 1);
117 22         94 my $dir = $self->{dir};
118              
119 22 50       286 if (-d $dir) {
120 22 100       405 if (-e "$dir/pid") {
121 5 50       485 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__