::Logging::TestLogger package decleration had wrong name
[scpubgit/Object-Remote.git] / lib / Object / Remote / WatchDog.pm
1 package Object::Remote::WatchDog; 
2
3 use Object::Remote::MiniLoop; 
4 use Object::Remote::Logging qw (:log :dlog router);
5 use Moo; 
6
7 has timeout => ( is => 'ro', required => 1 );
8
9 BEGIN { router()->exclude_forwarding; }
10
11 around new => sub {
12   my ($orig, $self, @args) = @_; 
13   our ($WATCHDOG);
14     
15   return $WATCHDOG if defined $WATCHDOG;
16   log_trace { "Constructing new instance of global watchdog" };
17   return $WATCHDOG = $self->$orig(@args);
18 };
19
20 #start the watchdog
21 sub BUILD {
22   my ($self) = @_;
23   
24   $SIG{ALRM} = sub {
25     #if the Watchdog is killing the process we don't want any chance of the
26     #process not actually exiting and die could be caught by an eval which
27     #doesn't do us any good 
28     log_fatal { "Watchdog has expired, terminating the process" };
29     exit(1);
30   };   
31   
32   Dlog_debug { "Initializing watchdog with timeout of $_ seconds" } $self->timeout;
33   alarm($self->timeout);
34 }
35
36 #invoke at least once per timeout to stop
37 #the watchdog from killing the process 
38 sub reset {
39   our ($WATCHDOG);
40   die "Attempt to reset the watchdog before it was constructed"
41     unless defined $WATCHDOG; 
42   
43   log_debug { "Watchdog has been reset" };
44   alarm($WATCHDOG->timeout); 
45 }
46
47 #must explicitly call this method to stop the
48 #watchdog from killing the process - if the
49 #watchdog is lost because it goes out of scope
50 #it makes sense to still terminate the process
51 sub shutdown {
52   my ($self) = @_;
53   log_debug { "Watchdog is shutting down" };
54   alarm(0); 
55 }
56
57 1;
58
59