Убедитесь, что администратор очередей демонов правильный

Может ли кто-нибудь взглянуть на мой скрипт PHP-демона или объяснить, как я могу проверить его на корректность? Я пытаюсь создать демон, который управляет очередью процессов, но мне нужно, чтобы демон не блокировал входящие сигналы, и я не уверен, что делаю это правильно.

Кроме того, в процессе демона есть цикл while, который постоянно проверяет время выполнения (через microtime (true)), будет проблема ЦП?

<?php

declare(ticks = 1); // how often to check for signals
define("FILE_ROTATE_MAX", 5); // Max number of log files to hold

ini_set('error_reporting', E_ALL);
ini_set("display_errors", 1);

// These define the signal handling
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP,  "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
pcntl_signal(SIGUSR2, "sig_handler");

//PID file should only hold my process id
define('PIDFILEPATH', dirname(__FILE__) . '/pid/' . basename(__FILE__) . '.pid');
define('LOGFILEPATH', dirname(__FILE__) . '/log/' . basename(__FILE__) . '.log');

function isProcessRunning( $pidFile = PIDFILEPATH) {
if (!file_exists($pidFile) || !is_file($pidFile)) return false;
$pid = file_get_contents($pidFile);
return posix_kill($pid, 0);
}

exec( 'rm -rf ' . dirname(__FILE__) . '/log/' . '*.std*' );

$cores = exec( 'nproc --all');

if( !preg_match('~^\d+$~', $cores) ){
$cores = exec( 'grep -c ^processor /proc/cpuinfo');
if( !preg_match('~^\d+$~', $cores) ){
exit('Could not find number of cores on system');
}
}

define('CORES', +$cores);
//define('MAX_PROCESSES', CORES * 2);

define('MAX_PROCESSES', 3);

if( isProcessRunning() ) {
die("Already running?\n");
}

if( false === file_put_contents(PIDFILEPATH, posix_getpid(), LOCK_EX) ) {
exit("Unable to write to pid file.");
}

register_shutdown_function('unlink', PIDFILEPATH);

function tick_handler() {
pcntl_signal_dispatch();
}

register_tick_function("tick_handler");

// check to see if we need to rotate the logs

$today = new DateTime('NOW');

// 0 (for Sunday) through 6 (for Saturday)
if( $today->format('w') == '5' ) {
if( !is_file( LOGFILEPATH . '-'. $today->format('Ymd') ) ) {
// need to rotate the logs
echo "need to rotate logs\n";
$bool = rename( LOGFILEPATH, LOGFILEPATH . '-'. $today->format('Ymd') );
if( !$bool ) {
echo "failed to rotate logs\n";
}
}
}

$signalQueue = [];

function sig_handler($signo) {
global $signalQueue;
$signalQueue []= $signo;

static $sigusr1_caught = 0;
static $sigusr2_caught = 0;

switch ($signo) {
case SIGTERM:
// handle shutdown tasks
echo "Caught SIGHUP...\n";
exit;
break;
case SIGHUP:
// handle restart tasks
echo "Caught SIGHUP...\n";
exit;
break;
case SIGUSR1:
$sigusr1_caught++;
echo "Caught SIGUSR1...\n";
break;
case SIGUSR2:
$sigusr2_caught++;
echo "Caught SIGUSR2...\n";
break;
case SIGINT:
echo "Caught SIGINT...\n";
echo sprintf("SIGUSR1's caught - %s\n", $sigusr1_caught );
echo sprintf("SIGUSR2's caught - %s\n", $sigusr2_caught );
exit;
break;
default:
// handle all other signals
echo "Caught Signal Number" . $signo;
//file_put_contents(LOGFILEPATH, "Caught Signal Number" . $signo . "\n" ,  LOCK_EX | FILE_APPEND);
exit;
break;
}
}

print "Daemon - PID: ".posix_getpid() . " GID: ".posix_getgid()  ."\n";

// Do something every minute
// or start a job or something$instances = [];

function spawnWorker($instanceID, $jobName) {
global $instances;

$logdir =  dirname(__FILE__) . '/log/';

$descriptorspec = array(
0 => array("file", $logdir . $instanceID. '.stdin'  ,"r"),  // stdin is a file that the child will read from
1 => array("file", $logdir . $instanceID. '.stdout' ,"w"),  // stdout is a file that the child will write to
2 => array("file", $logdir . $instanceID. '.stderr' , "a")  // stderr is a file that the child will append to
);

foreach($descriptorspec as $key => $innerArray) {
touch($innerArray['1']);
//exec(' >' . $innerArray['1']);
chmod($innerArray['1'], 0777);
}

//$cwd = '/tmp';
//$env = array('some_option' => 'aeiou');
//$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env);

static $seconds = 10;

$cmd = "php WorkerConfig.php {$jobName} {$seconds} ";
$process = proc_open($cmd, $descriptorspec, $pipes);

//$seconds = $seconds + 5;

if (is_resource($process)) {
$process_status = proc_get_status($process);
$instances[$instanceID] = $process_status['pid'];
}
}

$startTime = microtime(true);
$workerNumber = 0;
while( true ) {
// check for max time/timeout
$currentTime = microtime(true);
if( ($currentTime - $startTime) > 180 ) {
exit('max time reached');
}
// do work here
// check signal queue

while( ( count($instances) < MAX_PROCESSES ) && ($signal = array_shift($signalQueue)) ) {
switch ($signal) {
case SIGUSR1:
echo "Spawning worker # {$workerNumber}\n";
spawnWorker($workerNumber, 'Workflow');
$workerNumber++;
break;
case SIGUSR2:
echo "Caught SIGUSR2...\n";
break;
default:
echo "Don't know and don't care about this signal {$signal} \n";
break;
}
}

if( count($instances) ) {
echo 'waiting';
$child_pid = pcntl_waitpid(0, $status, WUNTRACED);

if( $child_pid == -1){
echo pcntl_strerror(pcntl_get_last_error());
exit('Error in pcntl_waitpid ');
}
else if( $child_pid == 0 ){
// if WNOHANG was used and no child was available
}
else {
$status = pcntl_wexitstatus($status);
echo "Child: {$child_pid}  |  Status: {$status} \n";
$index = array_search($child_pid, $instances);
if( $index !== false ) {
echo "Removing {$index}---{$child_pid} from instances array\n";
unset($instances[$index]);
}
}
}
}
exit;

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]