ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-Watchdog/Watchdog.pm
(Generate patch)

Comparing AnyEvent-Watchdog/Watchdog.pm (file contents):
Revision 1.1 by root, Sun Aug 2 14:51:29 2009 UTC vs.
Revision 1.6 by root, Sun Aug 30 17:20:27 2009 UTC

38Use AnyEvent::Watchdog to automatically restart the program 38Use AnyEvent::Watchdog to automatically restart the program
39when it fails to handle events for longer than 5 minutes: 39when it fails to handle events for longer than 5 minutes:
40 40
41 use AnyEvent::Watchdog qw(autorestart heartbeat=300); 41 use AnyEvent::Watchdog qw(autorestart heartbeat=300);
42 42
43=head1 FUNCTIONS 43=head1 VARIABLES/FUNCTIONS
44 44
45The module supports the following functions: 45The module supports the following variables and functions:
46 46
47=over 4 47=over 4
48 48
49=cut 49=cut
50 50
53# load modules we will use later anyways 53# load modules we will use later anyways
54use common::sense; 54use common::sense;
55 55
56use Carp (); 56use Carp ();
57 57
58our $VERSION = '0.1'; 58our $VERSION = '0.9';
59
60=item $AnyEvent::Watchdog::ENABLED
61
62This is true when the program is running under the regime of
63AnyEvent::Watchdog. Semi-obviously, you should I<NOT> C<use> or C<require>
64this module before looking at this variable, and neither should you try
65to load this module unless in the main program, rather use an idiom like
66this:
67
68 $AnyEvent::Watchdog::ENABLED
69 or die "watchdog not enabled...";
70 AnyEvent::Watchdog::restart (60); # MUST use ()
71
72Note that if this variable is defined, but false, then AnyEvent::Watchdog
73is running, but you are in the watchdog process - you probably did
74something very wrong in this case.
75
76=cut
59 77
60our $PID; # child pid 78our $PID; # child pid
61our $ENABLED = 1; 79our $ENABLED = 0;
62our $AUTORESTART; # actually exit 80our $AUTORESTART; # actually exit
63our $HEARTBEAT; 81our $HEARTBEAT;
64our ($P, $C); 82our ($P, $C);
65 83
66sub poll($) { 84sub poll($) {
118 136
119 } elsif ($cmd eq chr 3) { 137 } elsif ($cmd eq chr 3) {
120 sysread $P, my $interval, 1 138 sysread $P, my $interval, 1
121 or last; 139 or last;
122 140
123 $heartbeat = ord $interval 141 $heartbeat = ord $interval;
124 unless defined $heartbeat;
125 142
126 } elsif ($cmd eq chr 4) { 143 } elsif ($cmd eq chr 4) {
127 # heartbeat 144 # heartbeat
128 # TODO: should only reset heartbeat timeout with \005 145 # TODO: should only reset heartbeat timeout with \005
129 146
165 182
166our %SEEKPOS; 183our %SEEKPOS;
167# due to bugs in perl, try to remember file offsets for all fds, and restore them later 184# due to bugs in perl, try to remember file offsets for all fds, and restore them later
168# (the parser otherwise exhausts the input files) 185# (the parser otherwise exhausts the input files)
169 186
170# this causes perlio to flush it's handles internally, so 187# this causes perlio to flush its handles internally, so
171# seek offsets become correct. 188# seek offsets become correct.
172exec "."; # toi toi toi 189exec "."; # toi toi toi
173#{ 190#{
174# local $SIG{CHLD} = 'DEFAULT'; 191# local $SIG{CHLD} = 'DEFAULT';
175# my $pid = fork; 192# my $pid = fork;
179# } else { 196# } else {
180# kill 9, $$; 197# kill 9, $$;
181# } 198# }
182#} 199#}
183 200
184# now records all fd positions 201# now record "all" fd positions, assuming 1023 is more than enough.
185for (0 .. 1023) { 202for (0 .. 1023) {
186 open my $fh, "<&$_" or next; 203 open my $fh, "<&$_" or next;
187 $SEEKPOS{$_} = (sysseek $fh, 0, 1 or next); 204 $SEEKPOS{$_} = (sysseek $fh, 0, 1 or next);
188} 205}
189 206
204 221
205 unless (defined $PID) { 222 unless (defined $PID) {
206 warn "AnyEvent::Watchdog: '$!', retrying in one second...\n"; 223 warn "AnyEvent::Watchdog: '$!', retrying in one second...\n";
207 sleep 1; 224 sleep 1;
208 } elsif ($PID) { 225 } elsif ($PID) {
226 # parent code
209 close $C; 227 close $C;
210 server; 228 server;
211 } else { 229 } else {
230 # child code
231 $ENABLED = 1;
232
212 # restore seek offsets 233 # restore seek offsets
213 while (my ($k, $v) = each %SEEKPOS) { 234 while (my ($k, $v) = each %SEEKPOS) {
214 open my $fh, "<&$k" or next; 235 open my $fh, "<&$k" or next;
215 sysseek $fh, $v, 0; 236 sysseek $fh, $v, 0;
216 } 237 }
269twice as often. 290twice as often.
270 291
271Exit behaviour isn't changed, so if you want a restart instead of an exit, 292Exit behaviour isn't changed, so if you want a restart instead of an exit,
272you have to call C<autorestart>. 293you have to call C<autorestart>.
273 294
274Once enabled, the heartbeat cannot be switched off. 295The heartbeat frequency can be changed as often as you want, an interval
296of C<0> disables the heartbeat check again.
275 297
276=cut 298=cut
277 299
278sub heartbeat(;$) { 300sub heartbeat(;$) {
279 my ($interval) = @_; 301 my ($interval) = @_;
302 Carp::croak "AnyEvent::Watchdog: '$_' is not a valid import argument"; 324 Carp::croak "AnyEvent::Watchdog: '$_' is not a valid import argument";
303 } 325 }
304 } 326 }
305} 327}
306 328
329=back
330
307=head1 SEE ALSO 331=head1 SEE ALSO
308 332
309L<AnyEvent>. 333L<AnyEvent>.
310 334
311=head1 AUTHOR 335=head1 AUTHOR

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines