NAME Process - Interface for objects that represent generic computational processes VERSION Version 0.01 - Please note that this distribution is currently experimental 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 = MyProcessClass->new( ... ); my $rv = $object->run; if ( $rv ) { print "Thingy ran ok"; } else { print "Failed to run thingy"; } The "Process" family of classes is intented to be used as base classes for these types of objects. They are used to help identify process objects, and enforce a very limited API on these objects. The main intent is to provide a common base for objects that will be able to be used with various distributed processing systems. The scope of these 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 seperation 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 almost no functionality at all, and serves primarily to indicate that an object obeys the general rules of a "Process" class. 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 may or may not take arbitrary params, with specifics to be determined by each class. A default implementation which ignores 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 on this host" failure, return false. For blamed failure, 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 The "prepare" method is used to check object params and bind platform resources. The concept of object creation in "new" is seperated 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 provides a means to seperate checking of the params for general correctness from checking of params relative to the system the process is being run on. It additionally provides a good way to have errors remain attached to the object, and have them transported back across to the requesting host. Execution platforms are generally required to call "run" immediately after "prepare". As a result you should feel free to lock files and hold socket ports as they will be used immediately, and thus the only execution errors coming from "run" should be due to unexpected changes or race-condition issues. To restate, all possibly binding and checking should be done in "prepare" if at 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 propogated via storage in the object itself. The object should not return errors via exceptions. If you expect something you yourself use to potentially result in an exception, you should trap the exception and return false. 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 of the process was completed fully, regardless of any results from the process. Returns false if the process was interrupted, or an unexpected error occurs. 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 For other issues, contact the author. AUTHOR Adam Kennedy , COPYRIGHT Copyright 2006 Adam Kennedy. All rights reserved. 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.