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