yf_pcntl_signal classpcntl_signal handler static class.
| File | plugins/sys/classes/yf_pcntl_signal.class.php |
|---|---|
| Use | _class('pcntl_signal') |
A site sets them in its config with $PROJECT_CONF['pcntl_signal']['NAME'] = ...;
| Property | Default | Description |
|---|---|---|
static $LOG0_PATH |
'php://stdout' |
|
static $LOG1_PATH |
'php://stderr' |
|
static $log0_file |
null |
|
static $log1_file |
null |
public function pcntl_test()
public function pcntl_test()
{
if (is_console()) {
// var
$is_terminate = &self::$_pcntl_is_terminate;
$is_silent = &self::$_pcntl_is_silent;
echo PHP_EOL;
$count = 5;
while (true) {
echo 'Long action: ' . $count . ' sec';
for ($i = 0; $i < $count; $i++) {
echo '.';
sleep(1);
}
echo PHP_EOL;
// signal handler
$is_terminate = self::_pcntl_dispatch();
if ($is_terminate) {
echo 'break loop' . PHP_EOL;
break;
}
}
echo 'exit' . PHP_EOL;
}
}
_ hooks and helpers; not routable as page actionspublic function _init($options = null)
public function _init($options = null)
{
self::_pcntl_init($options);
}
public static function _pcntl_dispatch($options = null)
public static function _pcntl_dispatch($options = null)
{
$_pcntl_is_ttl = $_pcntl_ttl = $_pcntl_is_limit_action = $_pcntl_limit_action = $_pcntl_ts_start = $_pcntl_count_action = $_pcntl_is_exit = $_pcntl_is_terminate = $_pcntl_is_terminate_by_signal = $_pcntl_is_silent = $_is_exit = $_is_silent = null;
$result = false;
// import options, extract() overrides these defaults
$_is_exit = null;
$_is_silent = null;
is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
if (is_console()) {
// var
$ts = time();
$is_ttl = &self::$_pcntl_is_ttl;
$ttl = &self::$_pcntl_ttl;
$is_limit_action = &self::$_pcntl_is_limit_action;
$limit_action = &self::$_pcntl_limit_action;
$ts_start = &self::$_pcntl_ts_start;
$count_action = &self::$_pcntl_count_action;
$is_exit = &self::$_pcntl_is_exit;
$is_terminate = &self::$_pcntl_is_terminate;
$is_terminate_by_signal = &self::$_pcntl_is_terminate_by_signal;
$is_silent = &self::$_pcntl_is_silent;
$count_action++;
// signal
$__is_exit = isset($_is_exit) ? $_is_exit : $is_exit;
$__is_silent = isset($_is_silent) ? $_is_silent : $is_silent;
if ( ! ($__is_silent ?? null)) {
echo PHP_EOL;
}
$message_head = 'Going to terminate';
$message_type = [];
// signal
pcntl_signal_dispatch();
if ($is_terminate_by_signal) {
$is_terminate = true;
$message_type[] = 'signal';
}
// ttl
if ($is_ttl) {
$_ttl = $ts - $ts_start;
if ($_ttl >= $ttl) {
$is_terminate = true;
$message_type[] = 'limit ttl';
}
}
// action
if ($is_limit_action && $count_action >= $limit_action) {
$is_terminate = true;
$message_type[] = 'limit action';
}
// exit
if ($is_terminate) {
$result = true;
if ( ! ($__is_silent ?? null)) {
$message = $message_head;
if ($message_type) {
$message .= ' by ' . implode(', ', $message_type);
}
if ($message) {
echo $message . PHP_EOL;
}
}
if (($__is_exit ?? null)) {
exit(0);
}
}
}
return $result;
}
public static function _pcntl_dump($message = null, $var = null)
public static function _pcntl_dump($message = null, $var = null)
{
if ( ! ($message ?? null) && ! ($var ?? null)) {
return false;
}
! ($message ?? null) && $message = '';
$log = $var ? ' - ' . var_export($var, true) : '';
self::_pcntl_log($message . $log);
return true;
}
public static function _pcntl_error($message = null)
public static function _pcntl_error($message = null)
{
if ( ! ($message ?? null)) {
return false;
}
$title = 'Error: ';
self::_pcntl_log($title . $message . PHP_EOL, 'error');
return true;
}
public static function _pcntl_fatal($message = null, $code = -1)
public static function _pcntl_fatal($message = null, $code = -1)
{
if ( ! ($message ?? null)) {
return false;
}
$title = 'Fatal: ';
self::_pcntl_log($title . $message . PHP_EOL, 'error');
exit($code);
return true;
}
public static function _pcntl_init($options = null)
public static function _pcntl_init($options = null)
{
$_pcntl_ttl = $_pcntl_is_limit_action = $_pcntl_limit_action = $_pcntl_ts_start = $_pcntl_count_action = $_pcntl_is_exit = $_pcntl_is_terminate = $_pcntl_is_terminate_by_signal = $_pcntl_is_silent = $_pcntl_vars = $_is_error = null;
if (is_console()) {
// import options, extract() overrides these defaults
$_is_error = null;
is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
// var
$ts = time();
$ttl = &self::$_pcntl_ttl;
$is_limit_action = &self::$_pcntl_is_limit_action;
$limit_action = &self::$_pcntl_limit_action;
$ts_start = &self::$_pcntl_ts_start;
$count_action = &self::$_pcntl_count_action;
$is_exit = &self::$_pcntl_is_exit;
$is_terminate = &self::$_pcntl_is_terminate;
$is_terminate_by_signal = &self::$_pcntl_is_terminate_by_signal;
$is_silent = &self::$_pcntl_is_silent;
$vars = &self::$_pcntl_vars;
// vars init
foreach ($vars as $n) {
$_v = &${ '_' . $n };
if ( ! isset($_v)) {
continue;
}
${ $n } = $_v;
}
// start init
$ttl = 0;
$ts_start = $ts;
$count_action = 0;
$is_terminate = false;
$is_terminate_by_signal = false;
// ttl
self::_pcntl_ttl_calc();
// ini
ini_set('html_errors', 0);
error_reporting(E_ALL & ~E_NOTICE);
if (isset($_is_error) && $_is_error) {
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
}
ini_set('default_socket_timeout', -1);
}
}
public static function _pcntl_is_silent($options = null)
public static function _pcntl_is_silent($options = null)
{
return self::$_pcntl_is_silent;
}
public static function _pcntl_is_terminate($options = null)
public static function _pcntl_is_terminate($options = null)
{
return self::$_pcntl_is_terminate;
}
public static function _pcntl_is_terminate_by_signal($options = null)
public static function _pcntl_is_terminate_by_signal($options = null)
{
return self::$_pcntl_is_terminate_by_signal;
}
public static function _pcntl_log($options = null, $type = null)
public static function _pcntl_log($options = null, $type = null)
{
// import options, extract() overrides these defaults
$_message = null;
$_type = null;
is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
// message
if (is_string($options)) {
$_message = $options;
}
if ( ! ($_message ?? null)) {
return;
}
// file type
($_type ?? null) && $type = $_type;
$type = in_array($type, ['log', 'error']) ? $type : 'log';
// file
if ($type == 'log') {
$path = &self::$LOG0_PATH;
$file = &self::$log0_file;
} else {
$path = &self::$LOG1_PATH;
$file = &self::$log1_file;
}
if ( ! $file) {
$file = fopen($path, 'a');
}
// prepare: datetime, message
list($msec, $ts) = explode(' ', microtime());
$datetime = date('Y-m-d H-i-s', $ts);
$message = sprintf('[%s %3d] %s%s', $datetime, (int) ((float) $msec * 1000), $_message, PHP_EOL);
fwrite($file, $message);
}
public static function _pcntl_signal($signo = null, $signinfo = null)
public static function _pcntl_signal($signo = null, $signinfo = null)
{
// var
$is_terminate_by_signal = &self::$_pcntl_is_terminate_by_signal;
$is_silent = &self::$_pcntl_is_silent;
// signal
$signo = (int) $signo;
switch ($signo) {
case SIGINT:
case SIGTERM:
$is_terminate_by_signal = true;
break;
default:
if ( ! $is_silent) {
echo 'Signal not handled: ' . $signo . PHP_EOL;
}
}
}
public static function _pcntl_signal_init($options = null)
public static function _pcntl_signal_init($options = null)
{
if (is_console()) {
self::_pcntl_init($options);
$is_ttl = &self::$_pcntl_is_ttl;
$ttl = &self::$_pcntl_ttl;
$is_limit_action = &self::$_pcntl_is_limit_action;
$limit_action = &self::$_pcntl_limit_action;
$is_silent = &self::$_pcntl_is_silent;
// signal
if ( ! $is_silent) {
echo 'Process signal SIGINT, SIGTERM' . PHP_EOL;
}
pcntl_signal(SIGINT, __CLASS__ . '::_pcntl_signal');
pcntl_signal(SIGTERM, __CLASS__ . '::_pcntl_signal');
// ttl
if ($is_ttl) {
if ( ! $is_silent) {
echo 'Process limit ttl: ' . $ttl . PHP_EOL;
}
}
// action
if ($is_limit_action) {
if ( ! $is_silent) {
echo 'Process limit action: ' . $limit_action . PHP_EOL;
}
}
}
}
public static function _pcntl_ttl_calc()
public static function _pcntl_ttl_calc()
{
$is_ttl = &self::$_pcntl_is_ttl;
if ($is_ttl) {
$ttl_rnd = &self::$_pcntl_ttl_rnd;
$ttl_value = &self::$_pcntl_ttl_value;
$ttl = &self::$_pcntl_ttl;
if ($ttl_rnd > 0) {
$d = $ttl_value * $ttl_rnd / 100;
$t1 = $ttl_value - $d;
$t2 = $ttl_value + $d;
$ttl = mt_rand($t1, $t2);
($ttl_value > 0 && $ttl < 1) && $ttl = 1;
} else {
$ttl = $ttl_value;
}
}
}