File Coverage

blib/lib/Time/HiRes/Sleep/Until.pm
Criterion Covered Total %
statement 36 36 100.0
branch 5 6 83.3
condition 4 6 66.6
subroutine 11 11 100.0
pod 6 6 100.0
total 62 65 95.3


line stmt bran cond sub pod time code
1             package Time::HiRes::Sleep::Until;
2 1     1   83986 use strict;
  1         3  
  1         33  
3 1     1   6 use warnings;
  1         2  
  1         32  
4 1     1   5 use base qw{Package::New};
  1         1  
  1         496  
5 1     1   241 use Time::HiRes qw{};
  1         3  
  1         18  
6 1     1   469 use Math::Round qw{nhimult};
  1         1180  
  1         330  
7              
8             our $VERSION = '0.08';
9              
10             =head1 NAME
11              
12             Time::HiRes::Sleep::Until - Provides common ways to sleep until...
13              
14             =head1 SYNOPSIS
15              
16             use Time::HiRes::Sleep::Until;
17             my $su = Time::HiRes::Sleep::Until->new;
18             my $slept = $su->epoch($epoch); # epoch is a calculated time + $seconds
19             my $slept = $su->mark(20); # sleep until 20 second mark of the clock :00, :20, or :40
20             my $slept = $su->second(45); # sleep until 45 seconds after the minute
21              
22              
23             =head1 DESCRIPTION
24              
25             Sleep Until provides sleep wrappers for sleep functions that I commonly need. These methods are simply wrappers around L and L.
26              
27             We use this package to make measurements at the same time within the minute for integration with RRDtool.
28              
29             =head1 USAGE
30              
31             use strict;
32             use warnings;
33             use DateTime;
34             use Time::HiRes::Sleep::Until;
35             my $su=Time::HiRes::Sleep::Until->new;
36             do {
37             print DateTime->now, "\n"; #make a measurment three times a minute
38             } while ($su->mark(20));
39              
40             Perl One liner
41              
42             perl -MTime::HiRes::Sleep::Until -e 'printf "Slept: %s\n", Time::HiRes::Sleep::Until->new->top'
43              
44             =head1 CONSTRUCTOR
45              
46             =head2 new
47              
48             use Time::HiRes::Sleep::Until;
49             my $su=Time::HiRes::Sleep::Until->new;
50              
51             =head1 METHODS
52              
53             =head2 epoch
54              
55             Sleep until provided epoch in float seconds.
56              
57             while ($CONTINUE) {
58             my $sleep_epoch = $su->time + 60/8;
59             do_work(); #run process that needs to run back to back but not more than 8 times per minute
60             $su->epoch($sleep_epoch); #sleep(7.5 - runtime). if runtime > 7.5 seconds does not sleep
61             }
62              
63             =cut
64              
65             sub epoch {
66 8     8 1 1004131 my $self = shift;
67 8   50     50 my $epoch = shift || 0; #default is 1970-01-01 00:00
68 8         34 my $sleep = $epoch - Time::HiRes::time();
69 8 100       214569254 return $sleep <= 0 ? 0 : Time::HiRes::sleep($sleep);
70             }
71              
72             =head2 mark
73              
74             Sleep until next second mark;
75              
76             my $slept=$su->mark(20); # 20 second mark, i.e. 3 times a minute on the 20s
77             my $slept=$su->mark(10); # 10 second mark, i.e. 6 times a minute on the 10s
78             my $slept=$su->mark(6); # 6 second mark, i.e. 10 times a minute on 0,6,12,...
79              
80             =cut
81              
82             sub mark {
83 2     2 1 2171 my $time = Time::HiRes::time();
84 2         6 my $self = shift;
85 2   50     12 my $mark = shift || 0;
86 2 50       9 die("Error: mark requires parameter to be greater than zero.") unless $mark > 0;
87 2         10 my $epoch = nhimult($mark => $time); #next mark
88 2         47 return $self->epoch($epoch);
89             }
90              
91             =head2 second
92              
93             Sleep until the provided seconds after the minute
94              
95             my $slept=$su->second(0); #sleep until top of minute
96             my $slept=$su->second(30); #sleep until bottom of minute
97              
98             =cut
99              
100             sub second {
101 4     4 1 4473 my $time = Time::HiRes::time();
102 4         10 my $self = shift;
103 4   100     34 my $second = shift || 0; #default is top of the minute
104 4         28 my $min_next = nhimult(60 => $time);
105 4         94 my $min_last = $min_next - 60;
106 4 100       32 return $time < $min_last + $second
107             ? $self->epoch($min_last + $second)
108             : $self->epoch($min_next + $second);
109             }
110              
111             =head2 top
112              
113             Sleep until the top of the minute
114              
115             my $slept=$su->top; #alias for $su->second(0);
116              
117             =cut
118              
119             sub top {
120 2     2 1 4187 my $self=shift;
121 2         12 return $self->second(0);
122             }
123              
124             =head2 time
125              
126             Method to access Time::HiRes time without another import.
127              
128             =cut
129              
130 1     1 1 3971 sub time {return Time::HiRes::time()};
131              
132             =head2 sleep
133              
134             Method to access Time::HiRes sleep without another import.
135              
136             =cut
137              
138             sub sleep {
139 1     1 1 528 my $self = shift;
140 1         500179 return Time::HiRes::sleep(@_);
141             }
142              
143             =head1 LIMITATIONS
144              
145             The mathematics add a small amount of delay for which we do not account. Testing routinely passes with 100th of a second accuracy and typically with millisecond accuracy.
146              
147             =head1 BUGS
148              
149             Please log on RT and send an email to the author.
150              
151             =head1 SUPPORT
152              
153             DavisNetworks.com supports all Perl applications including this package.
154              
155             =head1 AUTHOR
156              
157             Michael R. Davis
158             CPAN ID: MRDVT
159             Satellite Tracking of People, LLC
160             mdavis@stopllc.com
161             http://www.stopllc.com/
162              
163             =head1 COPYRIGHT
164              
165             This program is free software licensed under the...
166              
167             The General Public License (GPL), Version 2, June 1991
168              
169             The full text of the license can be found in the LICENSE file included with this module.
170              
171             =head1 SEE ALSO
172              
173             L, L
174              
175             =cut
176              
177             1;