line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
101407
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
36
|
|
2
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
48
|
|
3
|
|
|
|
|
|
|
package Util::Timeout; |
4
|
|
|
|
|
|
|
BEGIN { |
5
|
1
|
|
|
1
|
|
68
|
$Util::Timeout::VERSION = '0.01'; |
6
|
|
|
|
|
|
|
} |
7
|
1
|
|
|
1
|
|
871
|
use POSIX qw{ceil}; |
|
1
|
|
|
|
|
7467
|
|
|
1
|
|
|
|
|
7
|
|
8
|
1
|
|
|
1
|
|
2051
|
use Exporter::Declare qw{-magic}; |
|
1
|
|
|
|
|
25279
|
|
|
1
|
|
|
|
|
5
|
|
9
|
|
|
|
|
|
|
use Sys::SigAction qw{timeout_call}; |
10
|
|
|
|
|
|
|
use Devel::Declare::Parser::Sublike; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# ABSTRACT: thin wrapper around Sys::SigAction::timeout_call |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 SYNOPSIS |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use Util::Timeout; |
17
|
|
|
|
|
|
|
timeout $seconds { ... } or do { ... }; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
retry $times { ... } or do { ... }; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 DESCRIPTION |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Sys::SigAction::timeout_call sets a timer for $seconds, if your code block is still running when the |
24
|
|
|
|
|
|
|
timer trips then it is killed off. timeout then returns a false value thus you can chain with 'or' |
25
|
|
|
|
|
|
|
to allow for a clean syntaticaly correct syntax |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 FUNCTIONS |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head2 timeout |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
timeout 1 { sleep(2) } or do { $error = 'timed out' }; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
REMEMBER: these are lexical blocks (like eval) so any vars that you want to use else where will |
34
|
|
|
|
|
|
|
need to be scoped as such. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Also note, due to alarm not allowing for decimal numbers, all values are rounded up. Any value given |
37
|
|
|
|
|
|
|
for $seconds that is <= 0 will shortcut and your code block will not be executed and 0 returned. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=cut |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
default_export timeout sublike { |
42
|
|
|
|
|
|
|
my ($seconds, $code) = @_; |
43
|
|
|
|
|
|
|
$seconds = ceil($seconds); |
44
|
|
|
|
|
|
|
return 0 unless $seconds > 0; |
45
|
|
|
|
|
|
|
return 0 unless defined $code && ref($code) eq 'CODE'; |
46
|
|
|
|
|
|
|
# invert return to allow the use of 'or' |
47
|
|
|
|
|
|
|
!timeout_call( $seconds, $code ); # 0 => timed out |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=head2 retry |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
my $num = 3; |
53
|
|
|
|
|
|
|
retry 5 { timeout 1 { sleep( $num-- ) } } or do { $error = 'timed out 5 times' }; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
retry will run your the code block, if the block returns true then we stop running and return '1'. |
56
|
|
|
|
|
|
|
If your code block returns false then it is run again, up to $times number of times (5 in the |
57
|
|
|
|
|
|
|
exampele), in this case rerun returns '0' allowing you to use 'or' like with timeout. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
$times is expeceted to be an int, any decimal value will be rounded up. If $times is <= 1 then |
60
|
|
|
|
|
|
|
your code block will not be run and 0 will be returned; |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=cut |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
default_export retry sublike { |
65
|
|
|
|
|
|
|
my ($times, $code) = @_; |
66
|
|
|
|
|
|
|
$times = ceil($times); |
67
|
|
|
|
|
|
|
return 0 unless $times >= 1; |
68
|
|
|
|
|
|
|
for (1..$times) { |
69
|
|
|
|
|
|
|
return 1 if &$code; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
return 0; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
1; |