예제 #1
0
파일: Process.php 프로젝트: hduwzy/test
 public static function init()
 {
     self::$pid = \posix_getpid();
     self::$ppid = \posix_getppid();
     self::$child = array();
     self::$alias = array();
     self::$user_events = array();
     self::$shm_to_pid = array();
     self::$status['start_time'] = time();
     // self::$shm_to_parent = -1;
     if (!self::$do_once) {
         // 初始化事件对象
         if (extension_loaded('libevent')) {
             self::$events = new Libevent();
         } else {
             self::$events = new Select();
         }
         self::$shm = new Shm(__FILE__, 'a');
         // 注册用户信号SIGUSR1处理函数
         self::onSysEvent(SIGUSR1, EventInterface::EV_SIGNAL, array("\\cli\\proc\\Process", 'defaultSigusr1Cbk'));
         // 注册子进程退出处理函数
         self::onSysEvent(SIGCHLD, EventInterface::EV_SIGNAL, array("\\cli\\proc\\Process", 'defaultSigchldCbk'));
         // 注册用户信号SIGUSR2处理函数
         self::onSysEvent(SIGUSR2, EventInterface::EV_SIGNAL, array("\\cli\\proc\\Process", 'defaultSigusr2Cbk'));
         // 注册exit回调函数
         register_shutdown_function(function () {
             Process::closeShm();
         });
         self::$do_once = true;
     }
 }
예제 #2
0
파일: Rpcmaster.php 프로젝트: hduwzy/test
 /**
  * socket事件回调函数
  * @param  [resource] $socket [服务器套接字]
  * @param  [int] $ev_tag [事件标志]
  * @param  [array] $args   [回调参数]
  * @return [none]
  */
 public function handle($socket = null, $ev_tag = null, $args = null)
 {
     // 回去远程命令
     date_default_timezone_set('Asia/Shanghai');
     if (null === $socket) {
         $cmds = new \stdClass();
         $cmds->command = '_finished_';
     } else {
         $rec_socket = stream_socket_accept($socket);
         $cmds = $this->_parseCmd($rec_socket);
     }
     if (empty($cmds)) {
         $cmds = array();
     }
     $cmds = is_object($cmds) ? array($cmds) : $cmds;
     $log_file = Flight::conf()->get('cli.sys.rpc_logpath') . date('Y-m-d') . '.log';
     // 逐个处理命令
     foreach ($cmds as $cmd) {
         if (!isset($cmd->params)) {
             $cmd->params = array();
         }
         $cur_cmd = $cmd;
         if ($cur_cmd->command == '_status_') {
             // 进程结束通知
             $status = array();
             $status['start_time'] = date('Y-m-d H:i:s', Process::$status['start_time']);
             $status['runing_list'] = $this->_runing_list;
             // $wait_cmd = array();
             // array_walk($this->_cmd_queue, function($v, $k)use(&$wait_cmd){
             // 	$wait_cmd[] = $v['command'];
             // });
             $status['waiting_list'] = $this->_cmd_queue;
             fwrite($rec_socket, json_encode($status));
             continue;
         } elseif ($cur_cmd->command == '_log_') {
             $tail_n = isset($cur_cmd->params[0]) ? (int) $cur_cmd->params[0] : 10;
             if (file_exists($log_file)) {
                 $log_data = `tail -n {$tail_n} {$log_file}`;
             }
             fwrite($rec_socket, json_encode($log_data));
             continue;
         } elseif ($cur_cmd->command == '_finished_') {
             // 进程结束通知
             $this->_shell_count--;
             // 正在运行的进程计数自减
             if ($queued_cmd = $this->shiftCmd()) {
                 // 一个进程结束后,判断队列是否有正在等待的命令,
                 // 有则唤起
                 $cur_cmd = $queued_cmd;
             } else {
                 // 队列中没有等待命令,忽略
                 continue;
             }
         } else {
             if ($this->_shell_count >= Flight::conf()->get('cli.sys.maxprocess')) {
                 // 正在运行的进程是否已经达到上限
                 // 是则插入等待队列,继续等待
                 $this->pushCmd($cur_cmd);
                 continue;
             } else {
                 $queued_cmd = $this->shiftCmd();
                 if (!empty($queued_cmd)) {
                     // 队列中有等待的命令,先处理
                     $this->pushCmd($cur_cmd);
                     $cur_cmd = $queued_cmd;
                 } else {
                     // 队列中没等待命令
                 }
             }
         }
         $process_cmd = $this->getProcessCmd($cur_cmd->command, $cur_cmd->params);
         if (false === $process_cmd) {
             continue;
         }
         $id = Process::fork($cur_cmd->command, $process_cmd['closure'], $process_cmd['params']);
         $log = date('H:i:s') . " start({$id}):" . json_encode($cur_cmd);
         $ret = `echo "{$log}" >> {$log_file}`;
         $this->_runing_list[$id] = $cur_cmd;
         $this->_spare_time[$id] = microtime(1);
         $this->_shell_count++;
     }
 }
예제 #3
0
파일: rpcserver.php 프로젝트: hduwzy/test
<?php

define('FLIGHT_ROOT', dirname(dirname(__DIR__)) . "/includes/flight");
define('BOOT_FILE', FLIGHT_ROOT . "/boot/boot.php");
require_once BOOT_FILE;
use rpc\Rpcserver;
use rpc\Rpcmaster;
use flight\Flight;
use cli\proc\Process;
use cli\events\EventInterface;
Flight::set('app.root', FLIGHT_ROOT);
Process::init();
$server = new Rpcserver();
$server->schema('tcp')->host(Flight::conf()->get('cli.sys.localhost'))->port(Flight::conf()->get('cli.sys.localport'))->create();
$rpc_master = new Rpcmaster();
Process::onSysEvent($server->getSocket(), EventInterface::EV_READ, array($rpc_master, 'handle'));
Process::loop();