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 <adamk@cpan.org>

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

COPYRIGHT
    Copyright 2006 - 2009 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.

