/usr/local/CPAN/Cluster-Init/Cluster/Init/DFA/Process.pm
package Cluster::Init::DFA::Process;
#
# AUTOMATICALLY GENERATED by ./dot2dfa
# Fri Apr 4 11:40:29 2003
# DO NOT EDIT
#
# Original .dot file contents included below __END__.
#
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(DFA_ACTIONS CONFIGURED DONE FAIL PASS PAUSING RUNBG RUNFG RUNNING RUNTEST SETUP STOPPING TESTING _ANY_ START STOP CHLD WAIT TEST RESPAWN ONCE OFF STARTED EXITED EXECFAILED CONTINUE TOO_RAPID TIMEOUT PROCRUNNING RC_ZERO RC_NONZERO);
our %EXPORT_TAGS = (constants => [qw(CONFIGURED DONE FAIL PASS PAUSING RUNBG RUNFG RUNNING RUNTEST SETUP STOPPING TESTING _ANY_ START STOP CHLD WAIT TEST RESPAWN ONCE OFF STARTED EXITED EXECFAILED CONTINUE TOO_RAPID TIMEOUT PROCRUNNING RC_ZERO RC_NONZERO)]);
my $debug = $ENV{DEBUG};
# Actions
# (you need to implement these in caller)
#
# Action => Value, # Events it can generate
#
use constant DFA_ACTIONS => (
CKFREQ => '$self->ckfreq(@arg)', # CONTINUE TOO_RAPID
CKMODE => '$self->ckmode(@arg)', # OFF ONCE RESPAWN TEST
# WAIT
CKPID => '$self->ckpid(@arg)', # CHLD PROCRUNNING START
# STOP TIMEOUT
CKRC => '$self->ckrc(@arg)', # RC_NONZERO RC_ZERO
ERROR => '$self->error(@arg)', #
KILLPROC => '$self->killproc(@arg)', # PROCRUNNING TIMEOUT
XEQ => '$self->xeq(@arg)', # EXECFAILED STARTED
);
my %const2act = DFA_ACTIONS;
# States
# use constant State => Value; # Events it can handle
#
use constant CONFIGURED => 'CONFIGURED'; # START
use constant DONE => 'DONE'; # EXITED OFF ONCE RESPAWN
# STOP WAIT
use constant FAIL => 'FAIL'; # START STOP
use constant PASS => 'PASS'; # START STOP
use constant PAUSING => 'PAUSING'; # CONTINUE STOP TOO_RAPID
use constant RUNBG => 'RUNBG'; # EXECFAILED EXITED
# STARTED STOP
use constant RUNFG => 'RUNFG'; # EXECFAILED EXITED
# STARTED STOP
use constant RUNNING => 'RUNNING'; # EXITED STOP
use constant RUNTEST => 'RUNTEST'; # EXECFAILED EXITED
# STARTED STOP
use constant SETUP => 'SETUP'; # OFF ONCE RESPAWN STOP
# TEST WAIT
use constant STOPPING => 'STOPPING'; # EXITED PROCRUNNING
# TIMEOUT
use constant TESTING => 'TESTING'; # RC_NONZERO RC_ZERO STOP
use constant _ANY_ => '_ANY_'; # CHLD START STOP
# Events
# use constant Event => Value; # States it can be accepted in
#
use constant START => 'START'; # CONFIGURED FAIL PASS
# _ANY_
use constant STOP => 'STOP'; # DONE FAIL PASS PAUSING
# RUNBG RUNFG RUNNING
# RUNTEST SETUP TESTING
# _ANY_
use constant CHLD => 'CHLD'; # _ANY_
use constant WAIT => 'WAIT'; # DONE SETUP
use constant TEST => 'TEST'; # SETUP
use constant RESPAWN => 'RESPAWN'; # DONE SETUP
use constant ONCE => 'ONCE'; # DONE SETUP
use constant OFF => 'OFF'; # DONE SETUP
use constant STARTED => 'STARTED'; # RUNBG RUNFG RUNTEST
use constant EXITED => 'EXITED'; # DONE RUNBG RUNFG
# RUNNING RUNTEST
# STOPPING
use constant EXECFAILED => 'EXECFAILED'; # RUNBG RUNFG RUNTEST
use constant CONTINUE => 'CONTINUE'; # PAUSING
use constant TOO_RAPID => 'TOO_RAPID'; # PAUSING
use constant TIMEOUT => 'TIMEOUT'; # STOPPING
use constant PROCRUNNING => 'PROCRUNNING'; # STOPPING
use constant RC_ZERO => 'RC_ZERO'; # TESTING
use constant RC_NONZERO => 'RC_NONZERO'; # TESTING
use constant GRAPH => {
CONFIGURED => {
START => { action => "CKMODE", newstate => "SETUP" },
STOP => { action => "", newstate => "CONFIGURED" },
},
DONE => {
CHLD => { action => "CKPID", newstate => "DONE" },
EXITED => { action => "CKMODE", newstate => "DONE" },
OFF => { action => "", newstate => "STOPPING" },
ONCE => { action => "", newstate => "DONE" },
RESPAWN => { action => "CKFREQ", newstate => "PAUSING" },
START => { action => "", newstate => "DONE" },
STOP => { action => "", newstate => "STOPPING" },
WAIT => { action => "", newstate => "DONE" },
},
FAIL => {
START => { action => "CKMODE", newstate => "SETUP" },
STOP => { action => "", newstate => "CONFIGURED" },
},
PASS => {
START => { action => "CKMODE", newstate => "SETUP" },
STOP => { action => "", newstate => "CONFIGURED" },
},
PAUSING => {
CHLD => { action => "CKPID", newstate => "PAUSING" },
CONTINUE => { action => "XEQ", newstate => "RUNBG" },
START => { action => "", newstate => "PAUSING" },
STOP => { action => "", newstate => "STOPPING" },
TOO_RAPID => { action => "", newstate => "PAUSING" },
},
RUNBG => {
CHLD => { action => "CKPID", newstate => "RUNBG" },
EXECFAILED => { action => "ERROR", newstate => "CONFIGURED" },
EXITED => { action => "CKMODE", newstate => "DONE" },
START => { action => "", newstate => "RUNBG" },
STARTED => { action => "", newstate => "DONE" },
STOP => { action => "", newstate => "STOPPING" },
},
RUNFG => {
CHLD => { action => "CKPID", newstate => "RUNFG" },
EXECFAILED => { action => "ERROR", newstate => "CONFIGURED" },
EXITED => { action => "CKMODE", newstate => "DONE" },
START => { action => "", newstate => "RUNFG" },
STARTED => { action => "", newstate => "RUNNING" },
STOP => { action => "", newstate => "STOPPING" },
},
RUNNING => {
CHLD => { action => "CKPID", newstate => "RUNNING" },
EXITED => { action => "CKMODE", newstate => "DONE" },
START => { action => "", newstate => "RUNNING" },
STOP => { action => "", newstate => "STOPPING" },
},
RUNTEST => {
CHLD => { action => "CKPID", newstate => "RUNTEST" },
EXECFAILED => { action => "ERROR", newstate => "CONFIGURED" },
EXITED => { action => "CKRC", newstate => "TESTING" },
START => { action => "", newstate => "RUNTEST" },
STARTED => { action => "", newstate => "RUNTEST" },
STOP => { action => "", newstate => "STOPPING" },
},
SETUP => {
OFF => { action => "", newstate => "CONFIGURED" },
ONCE => { action => "XEQ", newstate => "RUNBG" },
RESPAWN => { action => "XEQ", newstate => "RUNBG" },
START => { action => "", newstate => "SETUP" },
STOP => { action => "", newstate => "CONFIGURED" },
TEST => { action => "XEQ", newstate => "RUNTEST" },
WAIT => { action => "XEQ", newstate => "RUNFG" },
},
STOPPING => {
CHLD => { action => "CKPID", newstate => "STOPPING" },
EXITED => { action => "", newstate => "CONFIGURED" },
PROCRUNNING => { action => "KILLPROC", newstate => "STOPPING" },
START => { action => "", newstate => "STOPPING" },
STOP => { action => "", newstate => "STOPPING" },
TIMEOUT => { action => "CKPID", newstate => "STOPPING" },
},
TESTING => {
RC_NONZERO => { action => "", newstate => "FAIL" },
RC_ZERO => { action => "", newstate => "PASS" },
START => { action => "", newstate => "TESTING" },
STOP => { action => "", newstate => "CONFIGURED" },
},
_ANY_ => {
CHLD => { action => "CKPID", newstate => "_ANY_" },
START => { action => "", newstate => "_ANY_" },
STOP => { action => "", newstate => "_ANY_" },
},
};
my $num2str = {
"1" => "CONFIGURED",
"1024" => "STOPPING",
"1048576" => "OFF",
"128" => "RUNNING",
"131072" => "TEST",
"134217728" => "PROCRUNNING",
"16" => "PAUSING",
"16384" => "STOP",
"16777216" => "CONTINUE",
"2" => "DONE",
"2048" => "TESTING",
"2097152" => "STARTED",
"256" => "RUNTEST",
"262144" => "RESPAWN",
"268435456" => "RC_ZERO",
"32" => "RUNBG",
"32768" => "CHLD",
"33554432" => "TOO_RAPID",
"4" => "FAIL",
"4096" => "_ANY_",
"4194304" => "EXITED",
"512" => "SETUP",
"524288" => "ONCE",
"536870912" => "RC_NONZERO",
"64" => "RUNFG",
"65536" => "WAIT",
"67108864" => "TIMEOUT",
"8" => "PASS",
"8192" => "START",
"8388608" => "EXECFAILED",
};
my $str2num = {
CHLD => 32_768,
CONFIGURED => 1,
CONTINUE => 16_777_216,
DONE => 2,
EXECFAILED => 8_388_608,
EXITED => 4_194_304,
FAIL => 4,
OFF => 1_048_576,
ONCE => 524_288,
PASS => 8,
PAUSING => 16,
PROCRUNNING => 134_217_728,
RC_NONZERO => 536_870_912,
RC_ZERO => 268_435_456,
RESPAWN => 262_144,
RUNBG => 32,
RUNFG => 64,
RUNNING => 128,
RUNTEST => 256,
SETUP => 512,
START => 8192,
STARTED => 2_097_152,
STOP => 16_384,
STOPPING => 1024,
TEST => 131_072,
TESTING => 2048,
TIMEOUT => 67_108_864,
TOO_RAPID => 33_554_432,
WAIT => 65_536,
_ANY_ => 4096,
};
my %num2str = %$num2str;
my %str2num = %$str2num;
sub new
{
my $class=shift;
my $self = { @_ };
bless $self, ref($class) || $class;
$self->{graph}=GRAPH;
$self->{except}=\&except unless $self->{except};
$self->{entersuf} = "_enter" unless $self->{entersuf};
$self->{leavesuf} = "_leave" unless $self->{leavesuf};
$self->init() if $self->can('init');
return $self;
}
# set state blindly, running only the enter routine -- for use at startup
sub state
{
my ($self,$state)=@_;
if ($state)
{
die __PACKAGE__.": invalid state: ".$state."\n"
unless $self->{graph}{$state};
$self->{state}=$state;
my $enter = $state.$self->{entersuf};
$self->$enter($state) if $self->can($enter);
}
return $self->{state};
}
# feed event into state engine, then execute leave, action, and enter
# routines
sub tick
{
my ($self,$event,@arg) = @_;
die "usage: \$obj->tick(\$event[,\@arg])\n" unless $event;
@arg=() unless @arg;
my $numeric=0;
# $numeric = 1 if $event =~ /^\d+$/;
# $event=$num2str{$event} if $numeric;
my $graph = $self->{graph};
my $oldstate = $self->{state};
die __PACKAGE__.": initial state not set\n" unless $oldstate;
unless ($graph->{$oldstate}{$event})
{
return (&{$self->{except}}($oldstate,$event),'');
}
my $node = $graph->{$oldstate}{$event};
my $newstate = $node->{newstate};
my $action = $node->{action} || "";
my $statechg = ($newstate ne $oldstate);
$self->{state}=$newstate if $statechg;
my $leave = $oldstate.$self->{leavesuf};
my $enter = $newstate.$self->{entersuf};
$self->$leave($oldstate,$newstate,$action,@arg)
if $statechg && $self->can($leave);
$self->transit($oldstate,$newstate,$action,@arg)
if $self->can('transit');
$self->$enter($oldstate,$newstate,$action,@arg)
if $statechg && $self->can($enter);
return ($newstate,$action);
}
# default exception handler
sub except
{
my ($state,$event) = @_;
warn __PACKAGE__.": state '$state': unhandled event: ".$event."\n" if $debug;
return $state;
}
sub num2str
{
my $self=shift;
my $num=shift;
return $num2str{$num};
}
1;
__END__
digraph "Cluster::Init::DFA::Process"
{
size="7.5,10";
//rankdir=LR;
ratio=fill;
// _ANY_ -> _ANY_ [label="update/ckent"];
_ANY_ -> _ANY_ [label="start/"];
_ANY_ -> _ANY_ [label="stop/"];
// _ANY_ -> _ANY_ [label="restart/"];
_ANY_ -> _ANY_ [label="chld/ckpid"];
//async: start stop
configured -> setup [label="start/ckmode"];
// configured -> retired [label="retire/destruct"];
// sequencing -> setup [label="ready/ckmode"];
// sequencing -> sequencing [label="idle/ckseq"];
// sequencing -> configured [label="stop/"];
// sequencing -> retired [label="retire/destruct"];
setup -> runfg [label="wait/xeq"];
setup -> runtest [label="test/xeq"];
setup -> runbg [label="respawn/xeq"];
setup -> runbg [label="once/xeq"];
setup -> configured [label="stop/"];
setup -> configured [label="off/"];
// setup -> retired [label="retire/destruct"];
//async: start stop chld exited
runfg -> running [label="started/"];
runfg -> done [label="exited/ckmode"];
runfg -> configured [label="execfailed/error"];
runfg -> stopping [label="stop/"];
// runfg -> restarting [label="restart/"];
// runfg -> retiring [label="retire/"];
runtest -> runtest [label="started/"];
runtest -> testing [label="exited/ckrc"];
runtest -> configured [label="execfailed/error"];
runtest -> stopping [label="stop/"];
runbg -> done [label="started/"];
runbg -> done [label="exited/ckmode"];
runbg -> configured [label="execfailed/error"];
runbg -> stopping [label="stop/"];
// runbg -> restarting [label="restart/"];
// runbg -> retiring [label="retire/"];
running -> done [label="exited/ckmode"];
running -> stopping [label="stop/"];
// running -> restarting [label="restart/"];
// running -> retiring [label="retire/"];
done -> done [label="exited/ckmode"];
done -> done [label="wait/"];
// done -> testing [label="test/ckrc"];
done -> pausing [label="respawn/ckfreq"];
done -> done [label="once/"];
done -> stopping [label="stop/"];
done -> stopping [label="off/"];
// done -> restarting [label="restart/"];
// done -> retiring [label="retire/"];
pausing -> runbg [label="continue/xeq"];
pausing -> pausing [label="too_rapid/"];
pausing -> stopping [label="stop/"];
stopping -> stopping [label="timeout/ckpid"];
stopping -> stopping [label="procrunning/killproc"];
stopping -> configured [label="exited/"];
// restarting -> restarting [label="idle/ckpid"];
// restarting -> restarting [label="procrunning/"];
// restarting -> restarting [label="restart/"];
// restarting -> stopping [label="stop/"];
// restarting -> setup [label="procstopped/ckseq"];
// restarting -> setup [label="exited/ckseq"];
// restarting -> retiring [label="retire/"];
// retiring -> retiring [label="idle/ckpid"];
// retiring -> retiring [label="procrunning/"];
// retiring -> retired [label="procstopped/destruct"];
// retiring -> retired [label="exited/destruct"];
// retiring -> retiring [label="retire/"];
//async: start stop
testing -> pass [label="rc_zero/"];
testing -> fail [label="rc_nonzero/"];
testing -> configured [label="stop/"];
// testing -> restarting [label="restart/"];
// testing -> retired [label="retire/destruct"];
pass -> setup [label="start/ckmode"];
pass -> configured [label="stop/"];
// pass -> restarting [label="restart/"];
// pass -> retired [label="retire/destruct"];
fail -> setup [label="start/ckmode"];
fail -> configured [label="stop/"];
// fail -> restarting [label="restart/"];
// fail -> retired [label="retire/destruct"];
}