The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Google::Spreadsheet::Agent - A Distributed Agent System using Google Spreadsheets

VERSION

Version 0.02

SYNOPSIS

use Google::Spreadsheet::Agent;

my $google_agent = Google::Spreadsheet::Agent->new(
                                        agent_name => $goal,
                                        page_name => $google_page,
                                        debug => $debug,
                                        max_selves => $max, 
                                        bind_key_fields => {
                                             'foo' => 'this_particular_foo'
                                        },
                                        prerequisites => [ 'isitdone', 'isthisone' ],
                                        conflicts_with => {
                                                         'someother_agent.pl' => 3,
                                                         'someother_process' => 1
                                                       },
                                        subsumes => [ 'someothertask' ],
                                        );

$google_agent->run_my(sub {
                             print STDERR "THIS ONE PASSES!!!";
                             return 1;
                      });


$google_agent->run_my(sub {
                             print STDERR "THIS ONE FAILS AND EITHER EMAILS OR PRINTS THIS ERROR TO STDERR (depending on debug)!!!";
                             return;
                      });

$google_agent->run_my(sub {
                             print STDERR "THIS ONE PASSES AND UPDATES THE 'cool' field in the spreadsheet!!!";
                             return (1, {'cool' => 'really cool'});
                      });

DESCRIPTION

Google::Spreadsheet::Agent is a framework for creating massively distributed pipelines
across many different servers, each using the same google spreadsheet as a
control panel.  It is extensible, and flexible.  It doesnt specify what
goals any pipeline should be working towards, or which goals are prerequisites
for other goals, but it does provide logic for easily defining these relationships
based on your own needs.  It does this by providing a subsumption architecture,
whereby many small, highly focused agents are written to perform specific goals,
and also know what resources they require to perform them.  Agents can be coded to
subsume other agents upon successful completion.  In addition, it is
designed from the beginning to support the creation of simple human-computational
workflows.

CONFIGURATION

See Google::Spreadsheet::Agent::DB for information about how to configure your Agent.

METHODS

new

This method constructs a new instance of an Google::Spreadsheet::Agent.  An instance must
specify its name, the name of the Worksheet within the spreadsheet that it is
working off, and values for the required key_field(s) within the configuration
which will result in a single row being returned from the given spreadsheet.
Optionally, you can specify an ArrayRef of prerequisite fields in the spreadsheet
which must be true before the agent can run, whether to print out debug information
to the terminal, or email the errors using the configured email only on errors (default),
the maximum number of agents of this name to allow to run on the given machine,
and a HashRef of processes which, if a certain number are already running on the machine,
should cause the agent to exit without running.

required:
 agent_name => Str
 page_name => Str
 bind_key_fields => HashRef { key_field_name => bound_value, ... }

optional:
 prerequisites => []
 config || config_file
 debug => Bool
 max_selves => Int
 conflicts_with => { process_name => max_allowed, ... }
 subsumes => []

 This method will throw an exception if bind_key_fields are
 not supplied for required key_fields, as specified in the
 configuration.

 Also, there must be a field in the spreadsheet name for the agent_name.
 This field will be filled in with the status of the agent for a particular
 row, e.g. 1 for finished, r:hostname for running, or f:hostname for failure.

run_my

This method takes a subroutine codeRef as an argument.  It then checks to determine
if the agent needs to run for the given bind_key_field(s) specified row (it must
have a 1 in the 'ready' field for the row, and the agent_name field must be empty),
whether any prerequisite fields are true, whether the agent conflicts with something
else running on the machine, and whether there are not already max_selves other
instances of the agent running on the machine.  If all of these are true, it then
attempts to fill its hostname into the field for the agent_name.  If it succeeds,
it will then run the code_ref.  If it does not succeed (such as if an instance 
running on another server already chose that job and won the field) it exits.

The coderef can do almost anything it wants to do, but it must return one of the following:
return true
This instructs Google::Spreadsheet::Agent to place a 1 (true) value in the field for the agent on
the spreadsheet, signifying that it has completed successfully.  If the agent subsumes other agents,
the fields for these agents will also be set to 1.
return false
This instructs Google::Spreadsheet::Agent to place F:hostname into the field for the agent on the
spreadsheet, signifying that it has failed.  It will not run again for this job until the
failure is cleared from the spreadsheet (by any other agent).  Subsumed agent fields are left
as is.
return (true|false, HashRef)
This does what returning true or false does, as well as allowing specific fields in the 
spreadsheet to also be modified by the calling code.  The HashRef should contain keys
only for those fields to be updated (it should not attempt to update the field for the
agent_name itself, as this will be ignored).  Note, the fields for subsumed agents will
be set to 1 when the agent is successfull, overriding any values passed for these fields
in the returned HashRef, so it is best not to set these fields when returning 1 (success).
In addition, the coderef can print to STDOUT and STDERR.  If the agent was instantiated in
debug mode (true), it will print these to their normal destination.  If the agent was
instantiated without debug mode (the default), STDOUT and STDERR are captured, and, if
the codeRef returned false, emailed to the address specified in the configuration using the
same google account that configures access to the google spreadsheet.

One thing the agent must try at all costs to avoid is dying during the subref (e.g. use
eval for anything that you dont have control over).  It should always try to return one
of the valid return states so that the spreadsheet status can be updated correctly.

agent_name

This returns the name of the agent, in case it is needed by the calling code for other reasons.

debug

This returns the debug state specified in the constructor.

AUTHOR

Darin London, <darin.london at duke.edu>

BUGS

Please report any bugs or feature requests to bug-google-spreadsheet-agent at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Google-Spreadsheet-Agent. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Google::Spreadsheet::Agent

You can also look for information at:

SEE ALSO

Google::Spreadsheet::Agent::DB Google::Spreadsheet::Agent::Runner Net::Google::Spreadsheets Moose

COPYRIGHT & LICENSE

Copyright 2009 Darin London.

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.

PerlMonks Nodes

Note, these use an older Namespace IGSP::GoogleAgent instead of Google::Spreadsheet::Agent. RFC: 798154 Code: 798311