File Coverage

blib/lib/AnyEvent/Timer/Cron.pm
Criterion Covered Total %
statement 21 37 56.7
branch 0 8 0.0
condition 0 3 0.0
subroutine 7 11 63.6
pod 0 3 0.0
total 28 62 45.1


line stmt bran cond sub pod time code
1             package AnyEvent::Timer::Cron;
2 1     1   2418 use Moo;
  1         14565  
  1         6  
3              
4             our $VERSION = '0.002000';
5             $VERSION = eval $VERSION;
6              
7 1     1   2705 use AnyEvent;
  1         4169  
  1         47  
8 1     1   6 use Scalar::Util qw(weaken);
  1         1  
  1         86  
9 1     1   449 use Safe::Isa;
  1         351  
  1         124  
10 1     1   747 use DateTime;
  1         104223  
  1         44  
11 1     1   645 use DateTime::Event::Cron;
  1         47664  
  1         31  
12 1     1   454 use namespace::clean;
  1         7022  
  1         5  
13              
14             has 'cb' => (is => 'ro', required => 1);
15             has 'time_zone' => (is => 'ro');
16             has '_cron' => (
17             is => 'ro',
18             required => 1,
19             init_arg => 'cron',
20             coerce => sub {
21             my $cron = shift;
22             if (!ref $cron) {
23             $cron = DateTime::Event::Cron->new($cron);
24             }
25             if ($cron->$_can('next')) {
26             return sub { $cron->next(@_) };
27             }
28             elsif ($cron->$_can('get_next_valid_time_after')) {
29             return sub { $cron->get_next_valid_time_after(@_) };
30             }
31             die "Invalid cron!";
32             },
33             );
34             has '_timer' => (is => 'rw');
35              
36             sub BUILD {
37 0     0 0   my $self = shift;
38 0           $self->create_timer;
39             }
40              
41             sub create_timer {
42 0     0 0   my $self = shift;
43 0           weaken $self;
44 0           my $now = DateTime->from_epoch(epoch => AnyEvent->now);
45 0 0         $now->set_time_zone( $self->time_zone ) if $self->time_zone;
46 0           my $next = $self->next_event($now);
47             return
48 0 0         if not $next;
49 0           my $interval = $next->subtract_datetime_absolute($now)->in_units('nanoseconds') / 1_000_000_000;
50             $self->_timer(AnyEvent->timer(
51             after => $interval,
52             cb => sub {
53 0     0     $self->{cb}->();
54 0 0         $self && $self->create_timer;
55             },
56 0           ));
57             }
58              
59             sub next_event {
60 0     0 0   my $self = shift;
61 0   0       my $now = shift || DateTime->from_epoch(epoch => AnyEvent->now);
62 0 0         $now->set_time_zone( $self->time_zone ) if $self->time_zone;
63 0           $self->_cron->($now);
64             }
65              
66             1;
67             __END__