技术开发 频道

用PHP构建一个简易监视引擎

下面是定义该引擎的ServiceCheckRunner类:
class ServiceCheckRunner {  private $num_children;  private $services = array();  private $children = array();  public function _ _construct($conf, $num_children)  {   $loggers = array();   $this->num_children = $num_children;   $conf = simplexml_load_file($conf);   foreach($conf->loggers->logger as $logger) {    $class = new Reflection_Class("$logger->class");    if($class->isInstantiable()) {     $loggers["$logger->id"] = $class->newInstance();    }    else {     fputs(STDERR, "{$logger->class} cannot be instantiated.\n");     exit;    }   }   foreach($conf->services->service as $service) {    $class = new Reflection_Class("$service->class");    if($class->isInstantiable()) {     $item = $class->newInstance($service-params);     foreach($service->loggers->logger as $logger) {      $item->register_logger($loggers["$logger"]);     }     $this->services[] = $item;    }    else {     fputs(STDERR, "{$service->class} is not instantiable.\n");     exit;    }   }  }  private function next_attempt_sort($a, $b){   if($a->next_attempt() == $b->next_attempt()) {    return 0;   }   return ($a->next_attempt() < $b->next_attempt())? -1 : 1;  }  private function next(){   usort($this->services,array($this'next_attempt_sort'));   return $this->services[0];  }  public function loop(){   declare(ticks=1);   pcntl_signal(SIGCHLD, array($this"sig_child"));   pcntl_signal(SIGUSR1, array($this"sig_usr1"));   while(1) {    $now = time();    if(count($this->children)< $this->num_children) {     $service = $this->next();     if($now < $service->next_attempt()) {      sleep(1);      continue;     }     $service->set_next_attempt();     if($pid = pcntl_fork()) {      $this->children[$pid] = $service;     }     else {      pcntl_alarm($service->timeout());      exit($service->run());     }    }   }  }  public function log_current_status(){   foreach($this->services as $service) {    $service->log_current_status();   }  }  private function sig_child($signal){   $status = ServiceCheck::FAILURE;   pcntl_signal(SIGCHLD, array($this"sig_child"));   while(($pid = pcntl_wait($status, WNOHANG)) > 0){    $service = $this->children[$pid];    unset($this->children[$pid]);    if(pcntl_wifexited($status) && pcntl_wexitstatus($status) ==ServiceCheck::SUCCESS)    {     $status = ServiceCheck::SUCCESS;    }    $service->post_run($status);   }  }  private function sig_usr1($signal){   pcntl_signal(SIGUSR1, array($this"sig_usr1"));   $this->log_current_status();  } }
0
相关文章