/usr/local/CPAN/Cluster-Init/Cluster/Init/DFA/Daemon.pm
package Cluster::Init::DFA::Daemon;
#
# AUTOMATICALLY GENERATED by ./dot2dfa
# Sun Jul 20 00:38:34 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 ACCEPT CLTAB HALT HALTING LISTEN READLINE START TELLING _ANY_ TERM IDLE CLTAB_OK CLTAB_NOK SOCKETIO SOCKET_ERROR WRITETIME CLIENTIO TIMEOUT CMDERR TELL SHUTDOWN GROUP_NOK GROUPTOLD HALTED HALTTIME);
our %EXPORT_TAGS = (constants => [qw(ACCEPT CLTAB HALT HALTING LISTEN READLINE START TELLING _ANY_ TERM IDLE CLTAB_OK CLTAB_NOK SOCKETIO SOCKET_ERROR WRITETIME CLIENTIO TIMEOUT CMDERR TELL SHUTDOWN GROUP_NOK GROUPTOLD HALTED HALTTIME)]);
my $debug = $ENV{DEBUG};
# Actions
# (you need to implement these in caller)
#
# Action => Value, # Events it can generate
#
use constant DFA_ACTIONS => (
BYE => '$self->bye(@arg)', # HALTTIME
GETCMD => '$self->getcmd(@arg)', # CMDERR SHUTDOWN TELL
# TIMEOUT
HALTALL => '$self->haltall(@arg)', # HALTED
PUTRES => '$self->putres(@arg)', # HALTTIME SOCKET_ERROR
# WRITETIME
READ_CLTAB => '$self->read_cltab(@arg)', # CLTAB_NOK CLTAB_OK
# IDLE
START_LISTENER => '$self->start_listener(@arg)', # SOCKET_ERROR
# WRITETIME
TELLGROUP => '$self->tellgroup(@arg)', # GROUPTOLD GROUP_NOK
# SHUTDOWN
WATCH_CLIENT => '$self->watch_client(@arg)', # TIMEOUT
WRITESTAT => '$self->writestat(@arg)', # SOCKET_ERROR
# WRITETIME
);
my %const2act = DFA_ACTIONS;
# States
# use constant State => Value; # Events it can handle
#
use constant ACCEPT => 'ACCEPT'; # CLIENTIO TIMEOUT
use constant CLTAB => 'CLTAB'; # CLTAB_NOK CLTAB_OK
use constant HALT => 'HALT'; # HALTTIME
use constant HALTING => 'HALTING'; # HALTED
use constant LISTEN => 'LISTEN'; # SOCKETIO SOCKET_ERROR
# WRITETIME
use constant READLINE => 'READLINE'; # CMDERR SHUTDOWN TELL
# TIMEOUT
use constant START => 'START'; # CLTAB_NOK CLTAB_OK IDLE
use constant TELLING => 'TELLING'; # GROUPTOLD GROUP_NOK
# SHUTDOWN
use constant _ANY_ => '_ANY_'; # TERM
# Events
# use constant Event => Value; # States it can be accepted in
#
use constant TERM => 'TERM'; # _ANY_
use constant IDLE => 'IDLE'; # START
use constant CLTAB_OK => 'CLTAB_OK'; # CLTAB START
use constant CLTAB_NOK => 'CLTAB_NOK'; # CLTAB START
use constant SOCKETIO => 'SOCKETIO'; # LISTEN
use constant SOCKET_ERROR => 'SOCKET_ERROR'; # LISTEN
use constant WRITETIME => 'WRITETIME'; # LISTEN
use constant CLIENTIO => 'CLIENTIO'; # ACCEPT
use constant TIMEOUT => 'TIMEOUT'; # ACCEPT READLINE
use constant CMDERR => 'CMDERR'; # READLINE
use constant TELL => 'TELL'; # READLINE
use constant SHUTDOWN => 'SHUTDOWN'; # READLINE TELLING
use constant GROUP_NOK => 'GROUP_NOK'; # TELLING
use constant GROUPTOLD => 'GROUPTOLD'; # TELLING
use constant HALTED => 'HALTED'; # HALTING
use constant HALTTIME => 'HALTTIME'; # HALT
use constant GRAPH => {
ACCEPT => {
CLIENTIO => { action => "GETCMD", newstate => "READLINE" },
TIMEOUT => { action => "PUTRES", newstate => "LISTEN" },
},
CLTAB => {
CLTAB_NOK => { action => "PUTRES", newstate => "LISTEN" },
CLTAB_OK => { action => "TELLGROUP", newstate => "TELLING" },
},
HALT => { HALTTIME => { action => "BYE", newstate => "HALT" } },
HALTING => { HALTED => { action => "PUTRES", newstate => "HALT" } },
LISTEN => {
SOCKETIO => { action => "WATCH_CLIENT", newstate => "ACCEPT" },
SOCKET_ERROR => { action => "", newstate => "HALT" },
WRITETIME => { action => "WRITESTAT", newstate => "LISTEN" },
},
READLINE => {
CMDERR => { action => "PUTRES", newstate => "LISTEN" },
SHUTDOWN => { action => "HALTALL", newstate => "HALTING" },
TELL => { action => "READ_CLTAB", newstate => "CLTAB" },
TIMEOUT => { action => "PUTRES", newstate => "LISTEN" },
},
START => {
CLTAB_NOK => { action => "", newstate => "HALT" },
CLTAB_OK => { action => "START_LISTENER", newstate => "LISTEN" },
IDLE => { action => "READ_CLTAB", newstate => "START" },
},
TELLING => {
GROUPTOLD => { action => "PUTRES", newstate => "LISTEN" },
GROUP_NOK => { action => "PUTRES", newstate => "LISTEN" },
SHUTDOWN => { action => "HALTALL", newstate => "HALTING" },
},
_ANY_ => { TERM => { action => "HALTALL", newstate => "HALTING" } },
};
my $num2str = {
"1" => "ACCEPT",
"1024" => "IDLE",
"1048576" => "SHUTDOWN",
"128" => "TELLING",
"131072" => "TIMEOUT",
"16" => "LISTEN",
"16384" => "SOCKET_ERROR",
"16777216" => "HALTTIME",
"2" => "CLTAB",
"2048" => "CLTAB_OK",
"2097152" => "GROUP_NOK",
"256" => "_ANY_",
"262144" => "CMDERR",
"32" => "READLINE",
"32768" => "WRITETIME",
"4" => "HALT",
"4096" => "CLTAB_NOK",
"4194304" => "GROUPTOLD",
"512" => "TERM",
"524288" => "TELL",
"64" => "START",
"65536" => "CLIENTIO",
"8" => "HALTING",
"8192" => "SOCKETIO",
"8388608" => "HALTED",
};
my $str2num = {
ACCEPT => 1,
CLIENTIO => 65_536,
CLTAB => 2,
CLTAB_NOK => 4096,
CLTAB_OK => 2048,
CMDERR => 262_144,
GROUPTOLD => 4_194_304,
GROUP_NOK => 2_097_152,
HALT => 4,
HALTED => 8_388_608,
HALTING => 8,
HALTTIME => 16_777_216,
IDLE => 1024,
LISTEN => 16,
READLINE => 32,
SHUTDOWN => 1_048_576,
SOCKETIO => 8192,
SOCKET_ERROR => 16_384,
START => 64,
TELL => 524_288,
TELLING => 128,
TERM => 512,
TIMEOUT => 131_072,
WRITETIME => 32_768,
_ANY_ => 256,
};
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::Daemon"
{
size="7.5,10";
//rankdir=LR;
//ratio=fill;
_ANY_ -> halting [label="term/haltall"];
//async:
start -> start [label="idle/read_cltab"];
start -> listen [label="cltab_ok/start_listener"];
//async: socketio
start -> halt [label="cltab_nok/"];
listen -> accept [label="socketio/watch_client"];
//async: socketio clientio
listen -> halt [label="socket_error/"];
listen -> listen [label="writetime/writestat"];
accept -> readline [label="clientio/getcmd"];
accept -> listen [label="timeout/putres"];
readline -> listen [label="timeout/putres"];
readline -> listen [label="cmderr/putres"];
readline -> cltab [label="tell/read_cltab"];
readline -> halting [label="shutdown/haltall"];
cltab -> listen [label="cltab_nok/putres"];
cltab -> telling [label="cltab_ok/tellgroup"];
telling -> listen [label="group_nok/putres"];
telling -> listen [label="grouptold/putres"];
telling -> halting [label="shutdown/haltall"];
halting -> halt [label="halted/putres"];
halt -> halt [label="halttime/bye"];
}