File Coverage

blib/lib/Time/HiRes/Sleep/Until.pm
Criterion Covered Total %
statement 33 33 100.0
branch 5 6 83.3
condition 4 6 66.6
subroutine 9 9 100.0
pod 4 4 100.0
total 55 58 94.8


line stmt bran cond sub pod time code
1             package Time::HiRes::Sleep::Until;
2 1     1   36306 use strict;
  1         3  
  1         47  
3 1     1   6 use warnings;
  1         1  
  1         41  
4 1     1   5 use base qw{Package::New};
  1         6  
  1         716  
5 1     1   329 use Time::HiRes qw{sleep time};
  1         2  
  1         8  
6 1     1   864 use Math::Round qw{nhimult};
  1         3875  
  1         420  
7              
8             our $VERSION = '0.07';
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             $su->epoch(1420070400.0); # sleep until 2015-01-01 00:00
19             $su->mark(20); # sleep until 20 second mark of the clock :00, :20, or :40
20             $su->second(45); # sleep until 45 seconds after the minute
21              
22             =head1 DESCRIPTION
23              
24             Sleep Until provides sleep wrappers for sleep functions that I commonly need. These methods are simply wrappers around L and L.
25              
26             We use this package to make measurements at the same time within the minute for integration with RRDtool.
27              
28             =head1 USAGE
29              
30             use strict;
31             use warnings;
32             use DateTime;
33             use Time::HiRes::Sleep::Until;
34             my $su=Time::HiRes::Sleep::Until->new;
35             do {
36             print DateTime->now, "\n"; #make a measurment three times a minute
37             } while ($su->mark(20));
38              
39             Perl One liner
40              
41             perl -MTime::HiRes::Sleep::Until -e 'printf "Slept: %s\n", Time::HiRes::Sleep::Until->new->top'
42              
43             =head1 CONSTRUCTOR
44              
45             =head2 new
46              
47             use Time::HiRes::Sleep::Until;
48             my $su=Time::HiRes::Sleep::Until->new;
49              
50             =head1 METHODS
51              
52             =head2 epoch
53              
54             Sleep until provided epoch in float seconds.
55              
56             my $slept=$su->epoch($epoch); #epoch is simply a calculated time + $seconds
57              
58             =cut
59              
60             sub epoch {
61 8     8 1 1002583 my $self = shift;
62 8   50     29 my $epoch = shift || 0; #default is 1970-01-01 00:00
63 8         27 my $sleep = $epoch - time;
64 8 100       176957171 return $sleep <= 0 ? 0 : sleep($sleep);
65             }
66              
67             =head2 mark
68              
69             Sleep until next second mark;
70              
71             my $slept=$su->mark(20); # 20 second mark, i.e. 3 times a minute on the 20s
72             my $slept=$su->mark(10); # 10 second mark, i.e. 6 times a minute on the 10s
73             my $slept=$su->mark(6); # 6 second mark, i.e. 10 times a minute on 0,6,12,...
74              
75             =cut
76              
77             sub mark {
78 2     2 1 1066 my $time = time;
79 2         5 my $self = shift;
80 2   50     11 my $mark = shift || 0;
81 2 50       7 die("Error: mark requires parameter to be greater than zero.") unless $mark > 0;
82 2         10 my $epoch = nhimult($mark => $time); #next mark
83 2         45 return $self->epoch($epoch);
84             }
85              
86             =head2 second
87              
88             Sleep until the provided seconds after the minute
89              
90             my $slept=$su->second(0); #sleep until top of minute
91             my $slept=$su->second(30); #sleep until bottom of minute
92              
93             =cut
94              
95             sub second {
96 4     4 1 2420 my $time = time;
97 4         6 my $self = shift;
98 4   100     28 my $second = shift || 0; #default is top of the minute
99 4         22 my $min_next = nhimult(60 => $time);
100 4         74 my $min_last = $min_next - 60;
101 4 100       26 return $time < $min_last + $second
102             ? $self->epoch($min_last + $second)
103             : $self->epoch($min_next + $second);
104             }
105              
106             =head2 top
107              
108             Sleep until the top of the minute
109              
110             my $slept=$su->top; #alias for $su->second(0);
111              
112             =cut
113              
114             sub top {
115 2     2 1 3412 my $self=shift;
116 2         11 return $self->second(0);
117             }
118              
119             =head1 LIMITATIONS
120              
121             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.
122              
123             =head1 BUGS
124              
125             Please log on RT and send an email to the author.
126              
127             =head1 SUPPORT
128              
129             DavisNetworks.com supports all Perl applications including this package.
130              
131             =head1 AUTHOR
132              
133             Michael R. Davis
134             CPAN ID: MRDVT
135             Satellite Tracking of People, LLC
136             mdavis@stopllc.com
137             http://www.stopllc.com/
138              
139             =head1 COPYRIGHT
140              
141             This program is free software licensed under the...
142              
143             The General Public License (GPL), Version 2, June 1991
144              
145             The full text of the license can be found in the LICENSE file included with this module.
146              
147             =head1 SEE ALSO
148              
149             L, L
150              
151             =cut
152              
153             1;