File Coverage

blib/lib/Proc/Daemontools/Service.pm
Criterion Covered Total %
statement 36 37 97.3
branch 2 4 50.0
condition 2 3 66.6
subroutine 11 11 100.0
pod 5 5 100.0
total 56 60 93.3


line stmt bran cond sub pod time code
1             package Proc::Daemontools::Service;
2              
3 3     3   24146 use warnings;
  3         6  
  3         79  
4 3     3   11 use strict;
  3         6  
  3         72  
5 3     3   14 use Config;
  3         14  
  3         300  
6              
7             my (%SIGNUM, %SIGMETH);
8             BEGIN {
9 3     3   6 my $i = 0;
10 3         2559 for my $name (split ' ', $Config{sig_name}) {
11 207         10207 $SIGNUM{$name} = $i++;
12             }
13              
14             %SIGMETH = (
15 3         1298 INT => 'svc_interrupt',
16             HUP => 'svc_hangup',
17             TERM => 'svc_terminate',
18             ALRM => 'svc_alarm',
19             );
20             }
21              
22             =head1 NAME
23              
24             Proc::Daemontools::Service - services that play nicely with daemontools
25              
26             =head1 VERSION
27              
28             0.02
29              
30             =cut
31              
32             our $VERSION = '0.02';
33              
34             =head1 SYNOPSIS
35              
36             package Foo::Service;
37             use base qw(Proc::Daemontools::Service);
38              
39             sub svc_up { ... }
40              
41             # In other code...
42              
43             my $serv = Foo::Service->new;
44             $serv->run;
45              
46             =head1 DESCRIPTION
47              
48             See the daemontools page, at
49             L, and particularly the
50             svc page, at L.
51              
52             =head1 METHODS
53              
54             =head2 C<< new >>
55              
56             Takes no arguments (yet).
57              
58             =cut
59              
60             sub new {
61 2     2 1 1910 my $class = shift;
62 2 50       14 die "no arguments to new" if @_;
63 2         10 return bless {} => $class;
64             }
65              
66             =head2 C<< run >>
67              
68             Install signal handlers and call C<< svc_run >>, which
69             may continue indefinitely.
70              
71             If C<< svc_run >> ever finishes, calls C<< exit >>.
72              
73             =cut
74              
75             sub run {
76 1     1 1 285859 my $self = shift;
77 1         64 $self->install_handlers;
78 1         293 $self->svc_run;
79 0         0 $self->exit(0);
80             }
81              
82             =head2 C<< exit >>
83              
84             $serv->exit($exit_status);
85              
86             Exit, calling C<< svc_exit >> first if it exists. Default
87             signal handlers call this.
88              
89             =cut
90              
91             sub exit {
92 1     1 1 3 my $self = shift;
93 1 50       9 if ($self->can('svc_exit')) {
94 1         8 $self->svc_exit;
95             }
96 1         274 exit(shift);
97             }
98              
99             =head2 C<< install_handlers >>
100              
101             Install signal handlers to queue signals for processing by
102             C<< svc_* >> methods, below.
103              
104             NOTE: signal handlers are global. This means that two
105             instances of Proc::Daemontools::Service will fight with each
106             other. Don't do that.
107              
108             =cut
109              
110             sub install_handlers {
111 1     1 1 3 my $self = shift;
112 1         65 require sigtrap;
113 1         7 my @args;
114 1         33 for my $sig (qw(HUP INT TERM ALRM)) {
115 4     2   347 push @args, handler => sub { $self->_handle_signal($sig) } => $sig;
  2         25  
116             }
117 1         82 sigtrap->import(@args);
118             }
119              
120             sub _handle_signal {
121 2     2   5 my ($self, $signame) = @_;
122 2         21 my $arg = {
123             signame => $signame,
124             signum => $SIGNUM{$signame},
125             };
126 2   66     102 my $meth = $self->can($SIGMETH{$signame}) || $self->can('svc_default');
127 2         22 $self->$meth($arg);
128             }
129              
130             =head1 HOOKS
131              
132             =head2 C<< svc_run >>
133              
134             Called by C<< run >>. Your main program body should be here.
135              
136             =head2 C<< svc_exit >>
137              
138             Called by C<< exit >>. Any cleanup should be here. (optional)
139              
140             =head1 SIGNALS
141              
142             Subclasses should define their own copy of each of these
143             methods. They will be called by Proc::Daemontools::Service
144             as signals are caught.
145              
146             Names are taken from the full names of svc options.
147              
148             When called, these methods will be passed a hashref
149             indicating state.
150              
151             =over 4
152              
153             =item B
154              
155             the name of the signal (e.g. TERM)
156              
157             =item B
158              
159             the number of the signal (e.g. 15)
160              
161             =back
162              
163             =head2 C<< svc_hangup >>
164              
165             =head2 C<< svc_alarm >>
166              
167             =head2 C<< svc_interrupt >>
168              
169             =head2 C<< svc_terminate >>
170              
171             =head1 DEFAULT HANDLERS
172              
173             Uncaught signals will cause your program to exit. If your
174             package defines a C<< svc_exit >> method, it will be called
175             before exiting (see L).
176              
177             The exit value will be the number of the signal that caused
178             program exit.
179              
180             =head2 C<< svc_default >>
181              
182             Override this method to provide your own default for the
183             signals listed above.
184              
185             =cut
186              
187             sub svc_default {
188 1     1 1 3 my ($self, $arg) = @_;
189 1         27 $self->exit($arg->{signum});
190             }
191              
192             =head1 UNCATCHABLE SIGNALS
193              
194             =head2 C<< KILL >>
195              
196             =head2 C<< STOP >>
197              
198             =head2 C<< CONT >>
199              
200             Technically CONT isn't uncatchable; however, given that you
201             can't catch STOP, you probably don't want to catch CONT
202             either.
203              
204             =head1 AUTHOR
205              
206             Hans Dieter Pearcey, C<< >>
207              
208             =head1 BUGS
209              
210             Please report any bugs or feature requests to
211             C, or through the web interface at
212             L.
213             I will be notified, and then you'll automatically be notified of progress on
214             your bug as I make changes.
215              
216             =head1 ACKNOWLEDGEMENTS
217              
218             =head1 COPYRIGHT & LICENSE
219              
220             Copyright 2006 Hans Dieter Pearcey, all rights reserved.
221              
222             This program is free software; you can redistribute it and/or modify it
223             under the same terms as Perl itself.
224              
225             =cut
226              
227             1; # End of Proc::Daemontools::Service