File Coverage

blib/lib/Beam/Runnable/Timeout/Alarm.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1             package Beam::Runnable::Timeout::Alarm;
2             our $VERSION = '0.015';
3             # ABSTRACT: Use `alarm` to set a timeout for a command
4              
5             #pod =head1 SYNOPSIS
6             #pod
7             #pod ### In a Runnable module
8             #pod package My::Runnable::Script;
9             #pod use Moo;
10             #pod with 'Beam::Runnable', 'Beam::Runnable::Timeout::Alarm';
11             #pod has '+timeout' => ( default => 60 ); # Set timeout: 60s
12             #pod sub run { }
13             #pod
14             #pod ### In a container config file
15             #pod runnable:
16             #pod $class: My::Runnable::Script
17             #pod $with:
18             #pod - 'Beam::Runnable::Timeout::Alarm'
19             #pod timeout: 60
20             #pod
21             #pod =head1 DESCRIPTION
22             #pod
23             #pod This role adds a timeout for a runnable module using Perl's L
24             #pod function. When the timeout is reached, a warning will be printed to C and the
25             #pod program will exit with code C<255>.
26             #pod
27             #pod =head1 SEE ALSO
28             #pod
29             #pod L, L, L
30             #pod
31             #pod =cut
32              
33 1     1   570 use strict;
  1         3  
  1         34  
34 1     1   4 use warnings;
  1         6  
  1         24  
35 1     1   5 use Moo::Role;
  1         2  
  1         6  
36 1     1   325 use Types::Standard qw( Num CodeRef );
  1         2  
  1         9  
37 1     1   1182 use Time::HiRes qw( alarm );
  1         1487  
  1         5  
38              
39             #pod =attr timeout
40             #pod
41             #pod The time in seconds this program is allowed to run. This can include
42             #pod a decimal (like C<6.5> seconds).
43             #pod
44             #pod =cut
45              
46             has timeout => (
47             is => 'ro',
48             isa => Num,
49             required => 1,
50             );
51              
52             #pod =attr _timeout_cb
53             #pod
54             #pod A callback to be run when the timeout is reached. Override this to change
55             #pod what warning is printed to C and what exit code is used (or whether
56             #pod the process exits at all).
57             #pod
58             #pod =cut
59              
60             has _timeout_cb => (
61             is => 'ro',
62             isa => CodeRef,
63             default => sub {
64             warn "Timeout reached!\n";
65             exit 255;
66             },
67             );
68              
69             #pod =method run
70             #pod
71             #pod This role wraps the C method of your runnable class to add the timeout.
72             #pod
73             #pod =cut
74              
75             around run => sub {
76             my ( $orig, $self, @args ) = @_;
77             local $SIG{ALRM} = $self->_timeout_cb;
78             alarm $self->timeout;
79             return $self->$orig( @args );
80             };
81              
82             1;
83              
84             __END__