NAME

Async::Event::Interval - Timed and one-off asynchronous events

Coverage Status

SYNOPSIS

A simple event that updates JSON data from a website using a shared scalar variable, while allowing the main application to continue running in the foreground. Multiple events can be simultaneously used if desired.

See "EXAMPLES" for other various functionality of this module.

use warnings;
use strict;

use Async::Event::Interval;

my $event = Async::Event::Interval->new(2, \&callback);

my $shared_scalar_json = $event->shared_scalar;

$event->start;

while (1) {
    print "$$shared_scalar_json\n" if defined $$shared_scalar_json;

    # Do other things

    $event->restart if $event->error;
}

sub callback {
    $$shared_scalar_json = ...; # Fetch JSON from website
}

DESCRIPTION

Very basic implementation of asynchronous events with shared variables that are triggered by a timed interval. If a time of zero is specified, we'll run the event only once.

METHODS

new($delay, $callback, @params)

Returns a new Async::Event::Interval object. Does not create the event. Use start for that.

Parameters:

$delay

Mandatory: The interval on which to trigger your event callback, in seconds. Represent partial seconds as a floating point number. If zero is specified, we'll simply run the event once and stop.

$callback

Mandatory: A reference to a subroutine that will be called every time the interval expires.

@params

Optional, List: A list of parameters to pass to the callback. Note that these are not shared parameters and are a copy only, so changes to them in the main code will not be seen in the event, and vice-versa. See "shared_scalar" if you'd like to use variables that can be shared between the main application and the events.

start

Starts the event timer. Each time the interval is reached, the event callback is executed.

stop

Stops the event from being executed.

restart

Alias for start(). Re-starts a stop()ped event.

status

Returns the event's process ID (true) if it is running, 0 (false) if it isn't.

error

Returns true if an event crashed unexpectedly in the background, and false otherwise.

waiting

Returns true if the event is dormant and is ready for a start() or restart command. Returns false if the event is already running.

shared_scalar

Returns a reference to a scalar variable that can be shared between the main process and the events. This reference can be used within multiple events, and multiple shared scalars can be created by each event.

To read from or assign to the returned scalar, you must dereference it. Eg. $$shared_scalar = 1;.

id

Returns the integer ID of the event.

info

Returns a hash reference containing various data about the event. Eg.

$VAR1 = {
    'shared_scalars' => {
        '0x55435449' => \'hello, world!,
        '0x43534644' => \98
     },
    'pid' => 6841,
};

events

This is a class method that returns a hash reference that contains the data of all existing events. Call it with Async::Event::Interval::events().

$VAR1 = {
    '0' => {
        'shared_scalars' => {
            '0x555A4654' => \'hello, world',
            '0x4C534758' => \98
         },
        'pid' => 11859,
    },
    '1' => {
        'pid' => 11860
    }
};

EXAMPLES

Run Once

Send in an interval of zero (0) to have your event run a single time. Call start() repeatedly for numerous individual/one-off runs.

use Async::Event::Interval

my $event = Async::Event::Interval->new(0, sub {print "hey\n";});

$event->start;

# Do stuff, then run the event again if it's done its previous task

$event->start if $event->waiting;

Event Suicidal Timeout

You can have your callback commit suicide if it takes too long to run. We use Perl's $SIG{ALRM} and alarm() to do this. In your main application, you can check the status of the event and restart it or whatever else you need.

my $event_timeout = 30;

my $event = Async::Event::Interval->new(
    30,
    sub {
        local $SIG{ALRM} = sub { print "Committing suicide!\n"; kill 9, $$; };

        alarm $event_timeout;

        # Do stuff here. If it takes 30 seconds, we kill ourselves

        alarm 0;
    },
);

Event Parameters

You can send in a list of parameters to the event callback. Changing these within the main program will have no effect on the values sent into the event itself. These parameter variables are copies and are not shared. For shared variables, see "shared_scalar".

use Async::Event::Interval

my @params = qw(1 2 3);

my $event = Async::Event::Interval->new(
    1,
    \&callback,
    @params
);

sub callback {
    my ($one, $two, $three) = @_;
    print "$one, $two, $three\n";
}

Event crash: Restart event

use warnings;
use strict;

use Async::Event::Interval;

my $event = Async::Event::Interval->new(0.5, sub { kill 9, $$; });

$event->start;

sleep 1; # Do stuff

if ($event->error){
    print "Event crashed, restarting\n";
    $event->restart;
}

Event crash: End program

use warnings;
use strict;

use Async::Event::Interval;

my $event = Async::Event::Interval->new(0.5, sub { kill 9, $$; });

$event->start;

sleep 1; # Do stuff

die "Event crashed, can't continue" if $event->error;

AUTHOR

Steve Bertrand, <steveb at cpan.org>

LICENSE AND COPYRIGHT

Copyright 2022 Steve Bertrand.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.