Snippets

Brian Medley First round of Mojo::IOLoop based repeating events

Created by Brian Medley last modified
package Mojo::IOLoop::Repeating;

use Mojo::Base 'Mojo::EventEmitter';

use Mojo::IOLoop;
use Mojo::Loader qw(load_class);

use Date::Calc qw(Today_and_Now Add_Delta_DHMS Delta_DHMS Date_to_Time);
use Time::Crontab;

has events => sub { [] };

sub repeating {
    my $self = shift;

    my $time = time;
    my @now = Today_and_Now;

    my @start = @now;
    $start[-1] = 0;

    my (@offset) = Delta_DHMS(@start, @now);
    $offset[-1] = 60 - $offset[-1];

    my @next = Add_Delta_DHMS(@now, @offset);

    my $now = Date_to_Time(@now);
    my $next = Date_to_Time(@next);
    my $seconds = $next - $now;

    foreach my $event (@{ $self->events }) {
        my ($line, $pkg, $method) = @{ $event };

        if (my $e = load_class($pkg)) {
            die ref $e ? "Exception: $e" : 'Not found!';
        }

        my $time_cron = Time::Crontab->new($line);
        if ($time_cron->match($time)) {
            no strict qw(refs);

            &{ "${pkg}::$method" };
        }
    }
    
    Mojo::IOLoop->next_tick(sub {
        warn("seconds: $seconds");

        my $repeating = \&repeating;

        # Mojo::IOLoop->timer($seconds => \&repeating);
        Mojo::IOLoop->timer($seconds => sub { 
            $repeating->($self);
        });
    });
}

sub run {
    my $self = shift;

    my $repeating = \&repeating;

    Mojo::IOLoop->timer(1 => sub { 
        $repeating->($self);
    });

    Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
}

1;
package Stuff;

use Mojo::Base -strict;

sub minute {
    say("minute");
}

sub hour {
    say("hour");
}

sub five {
    say("five");
}

1;
package Mojolicious::Command::repeat;

use Mojo::Base 'Mojolicious::Command';

use Mojo::IOLoop::Repeating;

has description => 'Repeative events';
has usage       => "Usage: APPLICATION repeat\n";

sub run {
    my ($self, @args) = @_;

    my $repeat = Mojo::IOLoop::Repeating->new;

    $repeat->{events} = [
        ["* * * * *", "Stuff", "minute"],
        ["*/5 * * * *", "Stuff", "five"],
        ["0 * * * *", "Stuff", "hour"],
    ];

    $repeat->run;
}

1;
use Mojolicious::Lite;
 
plugin "Repeating";

get '/' => sub {
    my $c = shift;

    $c->render(text => 'Text!');
};
 
app->start;

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.