Skip to content

stevan/Stella

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stella

Actors for Perl

Stella is an implementation of the Actor Model for Perl.

This started out as a gist but I quickly decided that this path was fruitful and so created this module.

Observability

Stella is built with observability in mind and comes with a logging library that is also used internally within Stella. More details to come, but for now, try this:

> STELLA_LOG=4 perl -I lib t/001-basic.t

The STELLA_LOG value can be set to 1 (INFO), 2 (WARN), 3 (ERROR), 4 (DEBUG) and will produce colorful log output, especially the DEBUG setting. It provides a fairly decent insight as to what is going in inside the ActorSystem.

Example

use Stella;

class PingPong :isa(Stella::Actor) {
    use Stella::Tools::Debug; # import LOG_LEVEL, INFO, WARN, etc.

    field $name :param;  # so I can identify myself in the logs
    field $max  :param;  # the max number of ping/pong(s) to allow

    # counters for ping/pong(s)
    field $pings = 0;
    field $pongs = 0;

    field $logger;

    ADJUST {
        # create a logger if logging is enabled
        $logger = Stella::Tools::Debug->logger if LOG_LEVEL;
    }

    my sub _exit_both ($ctx, $a) {  $ctx->exit; $ctx->kill( $a ) }

    method Ping ($ctx, $message) {
        if ($pings < $max) {
            $logger->log_from( $ctx, INFO, "got Ping($name)[$pings] <= $max" ) if INFO;
            $ctx->send( $message->from, Stella::Event->new( symbol  => *Pong ) );
            $pings++;
        }
        else {
            $logger->log_from( $ctx, WARN, "!!! ending Ping at($name)[$pings] <= $max" ) if WARN;
            _exit_both( $ctx, $message->from );
        }
    }

    method Pong ($ctx, $message) {
        if ($pongs < $max) {
            $logger->log_from( $ctx, INFO, "got Pong($name)[$pongs] <= $max" ) if INFO;
            $ctx->send( $message->from, Stella::Event->new( symbol  => *Ping ) );
            $pongs++;
        }
        else {
            $logger->log_from( $ctx, WARN, "!!! ending Pong at($name)[$pongs] <= $max" ) if WARN;
            _exit_both( $ctx, $message->from );
        }
    }

    method behavior {
        Stella::Behavior::Method->new( allowed => [ *Ping, *Pong ] );
    }
}

sub init ($ctx) {
    # spawn 10 sets of Ping/Pong actors
    foreach ( 1 .. 10 ) {
        # give them a random max-pings
        my $max = int(rand(10));

        my $Ping = $ctx->spawn( Stella::ActorProps->new(
            class => 'PingPong',
            args  => { name => "Ping($_)", max => $max }
        ));
        my $Pong = $ctx->spawn( Stella::ActorProps->new(
            class => 'PingPong',
            args  => { name => "Pong($_)", max => $max }
        ));

        # start up this pair ...
        $Ping->send( $Pong, Stella::Event->new( symbol => *PingPong::Pong ) );
    }
}

Stella::ActorSystem->new( init => \&init )->loop;

SEE ALSO

This is (yet another) implementation of an ongoing project of mine to make a sensible Actor system for Perl. This version uses the newly released – but still experimental – class feature of Perl v5.38.

About

Actors for Perl

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages