NAME
Stepford::Planner - Takes a set of steps and figures out what order to run them in
VERSION
version 0.002009
SYNOPSIS
use Stepford::Planner;
my $planner = Stepford::Planner->new(
step_namespaces => 'My::Step',
);
$planner->run(
final_steps => [
'My::Step::DeployCatDatabase',
'My::Step::DeployDogDatabase',
],
config => {...},
);
DESCRIPTION
This class takes a set of objects which do the Stepford::Role::Step role and determines what order they should be run so as to get to one or more final steps.
Steps which are up to date are skipped during the run, so no unnecessary work is done.
METHODS
This class provides the following methods:
Stepford::Planner->new(...)
This method returns a new planner object. It accepts the following arguments:
step_namespaces
This argument is required.
This can either be a string or an array reference of strings. Each string should contain a namespace which contains step classes.
For example, if your steps are named
My::Step::CreateFoo
,My::Step::MergeFooAndBar
, andMy::Step::DeployMergedFooAndBar
, the namespace you'd provide is'My::Step'
.The order of the step namespaces is relevant. If more than one step has a production of the same name, then the first step "wins". Stepford sorts step class names based on the order of the namespaces provided to the constructor, and then the full name of the class. You can take advantage of this feature to provide different steps in a different environments (for example, for testing).
The planner object assumes that every class it finds in a step namespace is a step. Specifically, if it finds a package that is a subclass of Moose::Object, then it throws an error if that package does not also consume the Stepford::Role::Step role.
This means you can have utility packages and roles in a step namespace, but not Moose objects which aren't steps.
jobs
This argument default to 1.
The number of jobs to run at a time. By default, all steps are run sequentially. However, if you set this to a value greater than 1 then the planner will run steps in parallel, up to the value you set.
logger
This argument is optional.
This should be an object that provides
debug()
,info()
,notice()
,warning()
, anderror()
methods.This object will receive log messages from the planner and (possibly your steps).
If this is not provided, Stepford will create a Log::Dispatch object with a single Log::Dispatch::Null output (which silently eats all the logging messages).
Note that if you do provide a logger object of your own, Stepford will not load Log::Dispatch into memory.
$planner->run()
When this method is called, the planner comes up with a plan of the steps needed to get to the requested final steps.
When this method is called, we check for circular dependencies among the steps and will throw a Stepford::Error exception if it finds one. We also check for unsatisfied dependencies for steps in the plan. Finally, we check to make sure that no step provides its own dependencies as productions.
For each step, the planner checks if it is up to date compared to its dependencies (as determined by the $step->last_run_time()
method. If the step is up to date, it is skipped, otherwise the planner calls $step->run()
on the step.
Note that the step objects are always constructed, so you should avoid doing a lot of work in your constructor. Save that for the run()
method.
This method accepts the following parameters:
final_steps
This argument is required.
This can either be a string or an array reference of strings. Each string should be a step's class name. These classes must do the Stepford::Role::Step role.
These are the final steps run when the
$planner->run()
method is called.config
This is an optional hash reference. For each step constructed, the planner looks at the attributes that the step accepts. If they match any of the keys in this hash reference, the key/value pair from this hash reference will be passed to the step constructor. This matching is done based on attribute
init_arg
values.Note that values generated as productions from previous steps will override the corresponding key in the config hash reference.
$planner->step_namespaces()
This method returns the step namespaces passed to the constructor as a list (not an arrayref).
$planner->logger()
This method returns the logger
used by the planner, either what you passed to the constructor or a default.
PARALLEL RUN CAVEATS
When running steps in parallel, the results of a step (its productions) are sent from a child process to the parent by serializing them. This means that productions which can't be serialized (like a DBI handle) will probably blow up in some way. You'll need to find a way to work around this. For example, instead of passing a DBI handle you could pass a data structure with a DSN, username, password, and connection options.
AUTHOR
Dave Rolsky <drolsky@maxmind.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by MaxMind, Inc..
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.