NAME
   Process - Objects that represent generic computational processes

SYNOPSIS
     # Create the process
     my $object = MyProcess->new( ... )
         or die("Invalid configuration format");

 # Initialize it
     $object->prepare
         or die("Configuration not supportable");

 # Execute the process
     $object->run
         or die("Error while trying to execute the process");

DESCRIPTION
   There are a great number of situations in which you may want to model a
   computational process as an object.

   An implementation of this sort of object generally looks like the
   following when somebody uses it.

     my $object = MyProcessThingy->new( ... );

 my $rv = $object->run;

 if ( $rv ) {
         print "Thingy ran ok";
     } else {
         print "Failed to run thingy";
     }

   The "Process" family of modules are intended to be used as base and role
   classes for these types of objects. They are used to help identify
   process objects, and enforce a common API on these objects.

   The primary intent is to provide a common base for objects that will be
   able to be used with various distributed processing systems, without
   itself actually implementing any form of distributed system.

   The scope of uses for Process includes solutions to address the
   following scenarios.

   A single CPU on a single host
   Multiple CPUs on a single host
   Multiple hosts on a single network
   Hosts distributed across the internet
   Any processing resource accessible via any mechanism

   To put it another way, this family of classes is intended to addresses
   the separation of concerns between the processing of something, and the
   results of something.

   The actual ways in which the processes are run, and the handling of the
   results of the process are outside the scope of these classes.

   The "Process" class itself is the root of all of these classes. In fact,
   it is so abstract that it contains no functionality at all, and serves
   primarily to indicate that an object obeys the general rules of a
   "Process" class.

   Most of the basic "Process" modules are similar. They define how your
   object should behave (an API for a particular concept) without dictating
   a particular implementation.

   However, by using them, you are confirming to some processing system
   that your objects will obey particular rules, and thus can interact
   sanely with any processing system that follows the API.

 What You Can and Cannot Do
   The use of "Process" is mainly about making guarantees. Because this is
   Perl, it is not necesarily about enforcing those guarantees in a strict
   way. These sorts of guarantees need to be implemented at a language
   level to be meaningful in any case (for example, Perl's tainting or
   Haskell's monads). You may still hang yourself, but it's your own fault
   if you do.

   You may not alter the API of the three core methods
       It's always tempting to say "This acts like Foo, but we added an
       extra return condition for method bar". You may not do this.

       "Process" and a few other members of the family dictate all possible
       return values for "new", "prepare" and "run", and what state the
       objects should be in before and after these methods are called in
       the various cases. You may not break these rules, because larger
       systems will be depending on them to allow your objects to work with
       them flexibly and flawlessly.

   You may not store data in the surrounding Perl environment
       A "Process" object should be entirely self-contained when you are
       told to be. If your process is involved in creating or transforming
       information, then your implementation should keep these results
       inside the "Process" object. Do not store data elsewhere. This means
       no globals and no class-level variables. You can't leave error
       messages in a global $errstr variable, as some Perl modules do.

       This does not mean you can't store data in files. For "Process"
       objects that generate vast quantities of data it would be unwieldy
       to limit you to holding all data in memory at once. However any
       object data that refers to files should use absolute paths.

   You may not assume the timing of new and prepare.
       Most uses of "Process" will involve scheduling, transport, or
       otherwise mean that once a processing system has a "Process" object,
       it won't get to it immediately.

       You should not assume that "prepare" will be run immediately after
       "new" or in the same interpretor. You may however assume that "run"
       is run immediately after "prepare", and is in the same interpreter.

   You may not assume an object is unchanged after "run"
       A "Process" object may be unchanged after "run". Then again, it may
       also be completely changed, and have accumulated all sorts of data
       in it.

       This also means that you should not assume that a "Process" object
       can be run again after it completes. A specific class
       Process::Repeatable will be provided at a later date for this case.

   You may not interrelate with other Process objects
       In the default case, all "Process" objects are considered to be
       independent and standalone. They may not have any form of dependency
       on other "Process" objects, and they should not expect to
       communicate with any other "Process" objects.

       If you choose to add this type of functionality to your particular
       class that is fine, but any processing system will not be aware of
       this and thus will not be doing anything to help you out.

       Process::Depends will be provided at a later date for this case.

METHODS
 new
     my $object = MyClass->new( $configuration );
     if ( $object and $object->isa('Process') ) {
           print "Object created.\n";
     } else {
           print "Configuration not valid.\n";
     }

   The "new" constructor is required for all classes. It takes zero or more
   arbitrary params, with the specifics of any params outside the scope of
   this module. The specifics of any params are to be determined by each
   specific class.

   A default implementation which ignores any params and creates an empty
   object of a "HASH" type is provided as a convenience. However it should
   not be assumed that all objects will be a "HASH" type.

   For objects that subclass only the base "Process" class, and are not
   also subclasses of things like Process::Storable, the param-checking
   done in "new" should be thorough and and objects should be correct, with
   problems at "run"-time the exception rather than the rule.

   Returns a new "Process" object on success.

   For blame-free "Cannot support process in this Perl interpreter"
   failure, return false.

   For failure with blame, may return a string or any other value that is
   not itself a "Process" object.

   However, if you need to communicate failure, you should consider putting
   your param-checking in a "prepare" method and attaching the failure
   messages to the object itself. You should NEVER store errors in the
   class, as all "Process" classes are forbidden to use class-level data
   storage.

 prepare
     unless ( $object->prepare ) {
           # Failed
           die "Failed to prepare process";
     }

   The "prepare" method is used to check object params and bind platform
   resources.

   The concept of object creation in "new" is separated from the concept of
   checking and binding to support storage and transportation in some
   subclasses.

   Because many systems that make use of "Process" do so through the desire
   to push process requests across a network and have them executed on a
   remote host, "Process" provides the "prepare" method as a means to
   separate the checking of the params for general correctness from
   checking of params relative to the system and interpreter the process is
   being run on. It additionally provides a good way to have the bulk of
   serious errors remain attached to the object, and have them transported
   back across to the requesting entity.

   Execution platforms are required to call "run" immediately or nearly
   immediately after "prepare". Generally the only tasks done between
   "prepare" and "run" will be things like starting timers, setting flags
   and signalling to any requestor that the process is ok, and about to
   start.

   As a result you are encouraged to do all locking of files, socket ports,
   database handles and so on in "prepare", as they will be used
   immediately. Thus the only execution errors coming from "run" should be
   due to unexpected changes, race-condition events in the short gap
   between "prepare" and "run", or some error that could not possibly be
   detected until part way through the "run".

   To restate, resource binding and checking should be done in "prepare" if
   at all possible.

   A default null implementation is provided for you which does nothing and
   returns true.

   Returns true if all params check out ok, and all system resources needed
   for the execution are bound correctly.

   Returns false if not, with any errors to be propagated via storage in
   the object itself, for example in a "->{errstr}" attribute.

   The object should not return errors via exceptions. If you expect
   something within your code to potentially result in an exception, you
   should trap the exception and return false.

   You should not expect the object to be Storable or in any other way
   usable once the "Process" object is "prepare"'ed. The object is wound up
   and poised ready to "run" and that is the only thing you should do with
   it.

 run
     my $rv = $object->run;
     if ( $rv ) {
           print "Process completed successfully\n";
     } else {
           print "Process interupted, or unexpected error\n";
     }

   The "run" method is used to execute the process. It should do all
   appropriate processing and calculation and detach from all relevant
   resources before returning.

   If your process has any results, they should be stored inside the
   "Process" object itself, and retrieved via an additional method of your
   choice after the "run" call.

   A default implementation which does nothing and returns true is
   provided.

   Returns true if the "Process" was completed fully, regardless of any
   results from the process.

   Returns false if the process was interrupted, or an unexpected error
   occurs. In the default case for "Process", no distinction is made
   between the process being interrupted legitimately and any other type of
   unexpected failure.

   If the process returns false, it should not be assumed that the process
   can be restarted or rerun. It should be discarded or returned to the
   requestor to check for specific errors.

SUPPORT
   Bugs should be reported via the CPAN bug tracker at

   <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Process>

   For other issues, contact the author.

AUTHOR
   Adam Kennedy <[email protected]>

SEE ALSO
   <http://ali.as/>

COPYRIGHT
   Copyright 2006 - 2011 Adam Kennedy.

   This program is free software; you can redistribute it and/or modify it
   under the same terms as Perl itself.

   The full text of the license can be found in the LICENSE file included
   with this module.