Cluster-Init

 view release on metacpan or  search on metacpan

lib/Cluster/Init/Group.pm  view on Meta::CPAN

    # warn $tag;
    $db->ins($proc);
    $proc->start;
    my $w=$self->var(PROC,{var=>\$proc->{state}, poll=>'w'},$data);
    $proc->watchers($w);
    # $DB::single=1;
    return(NOOP,$data);
  }
  return(ALL_STARTED,$data);
}

sub ckproc
{
  my ($self,$data)=@_;
  my $db=$self->{db};
  my $group=$self->{group};
  # use $self->{level} here rather than $data->{level}; we want to
  # check against current rather than destination level (though they
  # should be the same)
  my $level=$self->{level};
  my (@proc) = $db->get('Cluster::Init::Process', {group=>$group});
  my ($done,$pass,$fail,$configured,$other,$total)=(0,0,0,0,0,0);
  for my $proc (@proc)
  {
    next unless $proc->haslevel($level);
    $total++;
    debug $proc->{tag}. " ". $proc->state;
    if ($proc->done){$done++;next}
    if ($proc->pass){$pass++;next}
    if ($proc->fail){$fail++;next}
    if ($proc->configured){$configured++;next}
    $other++;
  }
  debug "done $done pass $pass fail $fail configured $configured other $other total $total";
  return(NOOP,$data) if $other;
  return(ANY_FAILED,$data) if $fail;
  return(ALL_DONE,$data) unless $total;
  return(ALL_PASSED,$data) if $pass == $total;
  return(ALL_DONE,$data) if $done + $pass == $total;
  return(NOOP,$data) if $configured == $total;
  die "should never get here";
}

# Stop processes from other runlevels.
sub stopold
{
  my ($self,$data)=@_;
  my $db=$self->{db};
  my $group=$self->{group};
  my $level=$data->{level};
  affirm { defined($level) };
  my (@proc) = $db->get('Cluster::Init::Process', {group=>$group});
  for my $proc (@proc)
  {
    next if $proc->haslevel($level);
    next if $proc->configured;
    next if $proc->{kickme};
    my $tag = $proc->{tag};
    debug "stopping $tag level $level";
    # slap a kickme sign on this thing
    my $w=$self->timer(KICKME,{at=>time,interval=>1},$proc);
    $proc->watchers($w);
  }
  $self->timer(TIMEOUT,{at=>time+1},$data);
  return(NOOP,$data);
}

# stop all processes in group
sub haltgrp
{
  my ($self,$data)=@_;
  my $db=$self->{db};
  my $group=$self->{group};
  my (@proc) = $db->get('Cluster::Init::Process', {group=>$group});
  for my $proc (@proc)
  {
    next if $proc->configured;
    next if $proc->{kickme};
    my $tag = $proc->{tag};
    debug "halting $tag";
    # slap a kickme sign on this thing
    my $w=$self->timer(KICKME,{at=>time,interval=>1},$proc);
    $proc->watchers($w);
  }
  $self->timer(TIMEOUT,{at=>time+1},$data);
  return(NOOP,$data);
}

sub destruct
{
  my $self=shift;
  my $db=$self->{db};
  my $group=$self->{group};
  if ($db)
  {
    for my $proc ($db->get('Cluster::Init::Process', {group=>$group}))
    {
      $self->retire($proc);
    }
  }
  $self->SUPER::destruct;
  return 1;
}

sub kick
{
  my ($self,$proc)=@_;
  $proc->stop;
  return(NOOP);
}

sub ckstop
{
  my ($self,$data)=@_;
  my $db=$self->{db};
  my $group=$self->{group};
  my $level=$data->{level};
  affirm { defined($level) };
  my (@proc) = $db->get('Cluster::Init::Process', {group=>$group});
  for my $proc (@proc)
  {
    next if $proc->haslevel($level);
    next if $proc->configured;
    $self->timer(TIMEOUT,{at=>time+1},$data);
    return(NOOP,$data);
  }
  return(OLD_STOPPED,$data);
}
  
sub ckhalt
{
  my ($self,$data)=@_;
  my $db=$self->{db};
  my $group=$self->{group};
  my (@proc) = $db->get('Cluster::Init::Process', {group=>$group});
  my $stillthere;
  for my $proc (@proc)
  {
    debug "trying to halt: ".$proc->{tag}." ".$proc->state;
    $proc->stop;
    $self->retire($proc) if $proc->configured;
    $stillthere++;
  }
  if ($stillthere)
  {
    $self->timer(TIMEOUT,{at=>time+1},$data);
    return(NOOP,$data);
  }
  return(ALL_HALTED,$data);
}
  
# Garbage collect old, retired, or changed processes.  Assumes old
# processes have already been stopped gracefully.  Note that we don't
# try to do a soft stop here -- procs will get kill -9 if their
# cltab entry has been changed or deleted; might want to improve
# this in the future.  For now, the workaround is to always do a
# 'tell' to stop processes before editing cltab.
sub garbage_collect
{
  my ($self,$data)=@_;
  my $conf=$self->{conf};
  my $db=$self->{db};
  my $group=$self->{group};
  my $level=$data->{level};
  my (@oldproc) = $db->get('Cluster::Init::Process', {group=>$group});
  for my $oldproc (@oldproc)
  {
    my $tag = $oldproc->{tag};
    my ($newproc) = $conf->tag($tag);
    # deleted
    $self->retire($oldproc) unless $newproc;
    # changed 
    $self->retire($oldproc) if $newproc->{mode} ne $oldproc->{mode};
    $self->retire($oldproc) if $newproc->{cmd} ne $oldproc->{cmd};
    next if $oldproc->haslevel($level);
    # old level 
    $self->retire($oldproc);
  }
  return(CLEAN,$data);
}

sub retire
{
  my ($self,$proc)=@_;
  my $db=$self->{db};
  $proc->destruct;
  $db->del($proc);
}

sub XXXDONE_enter
{
  warn "in state DONE";
  $DB::single=1;
}

1;



( run in 1.000 second using v1.01-cache-2.11-cpan-39bf76dae61 )