File Coverage

blib/lib/XAS/Lib/Pidfile.pm
Criterion Covered Total %
statement 11 53 20.7
branch 1 18 5.5
condition n/a
subroutine 4 9 44.4
pod 3 3 100.0
total 19 83 22.8


line stmt bran cond sub pod time code
1             package XAS::Lib::Pidfile;
2              
3             our $VERSION = '0.01';
4             my $mixin;
5              
6             BEGIN {
7 1     1   3 $mixin = 'XAS::Lib::Pidfile::Unix';
8 1 50       25 $mixin = 'XAS::Lib::Pidfile::Win32' if ($^O eq 'MSWin32');
9             }
10              
11 1     1   4 use XAS::Factory;
  1         1  
  1         10  
12 1     1   83 use File::Basename;
  1         2  
  1         94  
13              
14             use XAS::Class
15 1         16 debug => 0,
16             version => $VERSION,
17             base => 'XAS::Base',
18             mixin => $mixin,
19             utils => 'trim dotid',
20             accessors => 'lockmgr lock',
21             filesystem => 'Dir',
22             vars => {
23             PARAMS => {
24             pid => 1,
25             file => { optional => 1, default => undef, isa => 'Badger::Filesystem::File' },
26             }
27             }
28 1     1   4 ;
  1         1  
29              
30             #use Data::Dumper;
31              
32             # ----------------------------------------------------------------------
33             # Public Methods
34             # ----------------------------------------------------------------------
35              
36             sub write {
37 0     0 1   my $self = shift;
38              
39 0           my $stat = 0;
40 0           my $lock = $self->lock;
41              
42             my $output = sub {
43              
44 0     0     my $fh = $self->file->open('w');
45 0           $fh->printf("%s\n", $self->pid);
46 0           $fh->close;
47              
48 0           };
49              
50 0 0         if ($self->lockmgr->lock($lock)) {
51              
52 0 0         if ($self->file->exists) {
53              
54 0           $output->();
55              
56             } else {
57              
58 0           $self->file->create();
59 0           $output->();
60              
61             }
62              
63 0           $stat = 1;
64 0           $self->lockmgr->unlock($lock);
65              
66             }
67              
68 0           return $stat;
69              
70             }
71              
72             sub remove {
73 0     0 1   my $self = shift;
74              
75 0           my $lock = $self->lock;
76 0           my $pid = $self->_get_pid;
77              
78 0 0         if ($pid == $$) {
79              
80 0 0         if ($self->lockmgr->lock($lock)) {
81              
82 0 0         $self->file->delete() if ($self->file->exists);
83 0           $self->lockmgr->unlock($lock);
84              
85             }
86              
87             }
88              
89             }
90              
91             # ----------------------------------------------------------------------
92             # Private Methods
93             # ----------------------------------------------------------------------
94              
95             sub _get_pid {
96 0     0     my $self = shift;
97              
98 0           my $pid = undef;
99 0           my $lock = $self->lock;
100              
101 0 0         if ($self->lockmgr->lock($lock)) {
102              
103 0 0         if ($self->file->exists) {
104              
105 0           my $fh = $self->file->open();
106 0           $pid = $fh->getline();
107 0           $pid = trim($pid);
108 0           $fh->close();
109              
110             }
111              
112 0           $self->lockmgr->unlock($lock);
113              
114             }
115              
116 0           return $pid
117              
118             }
119              
120             sub init {
121 0     0 1   my $class = shift;
122              
123 0           my $self = $class->SUPER::init(@_);
124              
125 0 0         unless (defined($self->{'file'})) {
126              
127 0           $self->{'file'} = $self->env->pid_file;
128              
129             }
130              
131 0           my $basename = fileparse($self->env->script, qr/\.[^.]*/);
132              
133 0           $self->{'lock'} = Dir($self->file->volume, $self->file->directory, $basename)->path;
134 0           $self->{'lockmgr'} = XAS::Factory->module('lockmgr');
135              
136 0           $self->lockmgr->add(
137             -key => $self->lock,
138             -driver => 'Filesystem',
139             );
140              
141 0           return $self;
142              
143             }
144              
145             1;
146              
147             __END__
148              
149             =head1 NAME
150              
151             XAS::Lib::PidFile - A class to manage pid files within XAS
152              
153             =head1 SYNOPSIS
154              
155             use XAS::Lib::PidFile;
156              
157             my $pid = XAS::Lib::PidFile->new(
158             -pid => $$,
159             -file => File('/', 'var', 'run', 'xas', 'process.pid')
160             );
161              
162             if ($pid->is_running) {
163              
164             printf("already running\n");
165             exit 2;
166              
167             }
168              
169             $pid->write();
170            
171             ...
172            
173             $pid->remove();
174            
175             =head1 DESCRIPTION
176              
177             This class will manage pid files for XAS. It loads mixins for individual
178             platforms to help with determining if a process is already running. It
179             uses discretionary directory locking to control access to the pid files.
180              
181             =head1 METHODS
182              
183             =head2 new
184              
185             This method initialize the module and takes this optional parameters.
186              
187             =over 4
188              
189             =item B<-file>
190              
191             Specifiy a pid file to use. This defaults to the pid file defined by
192             L<XAS::Lib::Modules::Environment> for the current procedure.
193              
194             =item B<-pid>
195              
196             Define a pid number. This must be supplied
197              
198             =back
199              
200             =head2 is_running
201              
202             This method is loaded thru a mixin. It will attempt to load a currently
203             existing pid file and check to see if that pid is active and if that
204             running process is the same as the current procedure.
205              
206             If it is, then it will return true. If not then it will return false.
207              
208             =head2 write
209              
210             Write the current pid to the pid file.
211              
212             =head2 remove
213              
214             Remove the current pid file.
215              
216             =head1 SEE ALSO
217              
218             =over 4
219              
220             =item L<XAS::Lib::Pidfile::Unix|XAS::Lib::Pidfile::Unix>
221              
222             =item L<XAS::Lib::Pidfile::Win32|XAS::Lib::Pidfile::Win32>
223              
224             =item L<XAS|XAS>
225              
226             =back
227              
228             =head1 AUTHOR
229              
230             Kevin L. Esteb, E<lt>kevin@kesteb.usE<gt>
231              
232             =head1 COPYRIGHT AND LICENSE
233              
234             Copyright (c) 2012-2015 Kevin L. Esteb
235              
236             TThis is free software; you can redistribute it and/or modify it under
237             the terms of the Artistic License 2.0. For details, see the full text
238             of the license at http://www.perlfoundation.org/artistic_license_2_0.
239              
240             =cut