The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Argon::Client

SYNOPSIS

    use Argon::Client;

    # Connect
    my $client = Argon::Client->new(host => '...', port => XXXX);

    # Send task and wait for result
    my $the_answer = $client->queue(sub {
        my ($x, $y) = @_;
        return $x * $y;
    }, [6, 7]);

    # Send task and get a deferred result that can be synchronized later
    my $deferred = $client->defer(sub {
        my ($x, $y) = @_;
        return $x * $y;
    }, [6, 7]);

    my $result = $deferred->();

    # Close the client connection
    $client->shutdown;

DESCRIPTION

Establishes a connection to an Argon network and provides methods for executing tasks and collecting the results.

METHODS

new(host => $host, port => $port)

Creates a new Argon::Client. The connection is made lazily when the first call to "queue" or "connect" is performed. The connection can be forced by calling "connect".

connect

Connects to the remote host.

server_status

Returns a hash of status information about the manager's load, capacity, and workers.

queue($f, $args, $pri, $max_tries)

Queues a task with the Argon::Manager and returns a message id which can be used to collect the results at a later time. The results are stored for at least $Argon::DEL_COMPLETE_AFTER seconds.

Similarly, a class implementing 'new' and 'run' methods may be used in place of a CODE ref:

    my $msgid = $client->queue('Task::Whatever', $args);
    # Executes Task::Whatever->new(@$args)->run();

This avoids import and closure issues that can occur when passing in a CODE reference.

$f <code ref|string>

Subroutine to execute or a task class implementing new(@$args) and run.

$args <array ref>

Arguments to pass to $f.

$pri <int|undef - $Argon::PRI_(LOW|NORMAL|HIGH) constant>

Task priority. Affects how the task is queued with the Manager when load is high enough that tasks are not immediately serviced. Defaults to $Argon::PRI_NORMAL.

$max_tries <int|undef>

When Manager's queue is full, new tasks are rejected until the queue is reduced. Tasks will be retried up to 10 times (by default) until they are accepted by the manager. If the task has not been accepted after $max_tries, an error is thrown.

collect($msgid)

Blocks the thread until the result identified by $msgid is available and returns the result. If processing the task resulted in an error, the error is rethrown when collect is called.

process($f, $args, $pri, $max_tries)

Equivalent to calling:

    my $msg = $client->queue($f, $args, $pri, $max_tries);
    my $result = $client->collect($msg);

defer($f, $args)

Similar to "process", but instead of waiting for the result, returns an anonymous function that, when called, waits and returns the result. If an error occurs when calling <$f>, it is re-thrown from the anonymous function.

defer accepts a either a CODE ref or a task class.

shutdown

Disconnects from the Argon network.

A NOTE ABOUT SCOPE

Storable is used to serialize code that is sent to the Argon network. This means that the code sent will not have access to variables and modules outside of itself when executed. Therefore, the following will not work:

    my $x = 0;
    $client->queue(sub { return $x + 1 }); # $x not found!

The right way is to pass it to the function as part of the task's arguments:

    my $x = 0;

    $client->queue(sub {
        my $x = shift;
        return $x + 1;
    }, [$x]);

Similarly, module imports are not available to the function:

    use Data::Dumper;

    my $data = [1,2,3];
    my $string = $client->queue(sub {
        my $data = shift;
        return Dumper($data); # Dumper not found
    }, [$data]);

The right way is to import the module inside the task:

    my $data = [1,2,3];
    my $string = $client->queue(sub {
        require Data::Dumper;
        my $data = shift;
        return Data::Dumper::Dumper($data);
    }, [$data]);

Note the use of require instead of use. This is because use is performed at compilation time, causing it to be triggered when the calling code is compiled, rather than from within the worker process. require, on the other hand, is triggered at runtime and will behave as expected.

Using a task class avoids this issue entirely; the task is loaded within the Argon worker process at run time, including any use or require statements.

AUTHOR

Jeff Ober <jeffober@gmail.com>