<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                >[danger] 20180415日進行了修改 > >使用參見教程 高階篇七 > ~~~ <?php /** * Created by PhpStorm. * User: Mikkle * QQ:776329498 * Date: 2017/10/19 * Time: 10:10 */ namespace mikkle\tp_worker; use mikkle\tp_master\Db; use mikkle\tp_master\Exception; use mikkle\tp_master\Log; use mikkle\tp_tools\Time; abstract class CycleWorkBase { protected $listName; protected $redis; protected $workList; protected $workerName; public static $instance; protected $connect =[] ; protected $saveLog=false; protected $tableName = "mk_log_service_queue"; protected $error; protected $stopTime; protected $startTime; protected $nextTime=60; /** * Base constructor. * @param array $options */ public function __construct($options=[]) { $this->_initialize(); $this->redis = $this->redis(); $this->workList = "worker_list"; $this->workerName = get_called_class(); $this->listName = md5($this->workerName); } public function _initialize(){ } abstract protected function runCycleHandle($data); protected function runHandle($data) { try{ $instance=self::instance(); $i =0; while ( true ){ echo self::checkWorkingStop() ; if ( self::checkWorkingStop() ){ echo "任務被終止!"; break; } $i++; self::signWorking(); $time = $instance->getNextRunTime(); if (!empty($instance->startTime ) && is_int( $instance->startTime ) ){ if ( time()>strtotime( $instance->startTime )){ $instance->pcntlWorker($data,"runCycleHandle"); Log::notice("執行了程序pcntlWorker".$this->workerName ); }else{ $this->sleep($time); Log::notice("未到執行時間_".$instance->startTime); continue; } }else{ $instance->pcntlWorker($data,"runCycleHandle"); $this->sleep($time); Log::notice("執行了程序pcntlWorker".$this->workerName ); } Log::notice("睡眠$time 秒,循環執行程序執行程序".$this->workerName ); echo "睡眠$time 秒,循環執行程序執行程序.$this->workerName "; } $this-> clearWorkingWork(); Log::notice("循環執行程序執結束"); }catch (Exception $e){ Log::notice( $e ->getMessage()); } } protected function getNextRunTime(){ if (!empty( $this->nextTime ) && is_int( $this->nextTime)){ return $this->nextTime; } return 10; } /** * @title redis * @description redis加載自定義Redis類 * User: Mikkle * QQ:776329498 * @return \mikkle\tp_redis\Redis */ protected static function redis() { return WorkerRedis::instance(); } /** * @title runWorker * @description 標注命令行執行此任務 * User: Mikkle * QQ:776329498 * @param string $handleName */ public function runWorker($handleName="run"){ $this->redis->hset($this->workList,$this->workerName,$handleName); } /** * 標注命令行清除此任務 * Power: Mikkle * Email:776329498@qq.com */ public function clearWorker(){ $this->redis->hDel("cycle_list",$this->listName); $this->redis->hdel($this->workList,$this->workerName); } /** * Power: Mikkle * Email:776329498@qq.com * @return static */ static public function instance(){ if (self::$instance){ return self::$instance; } return new static(); } /** * * 當命令行未運行 直接執行 * description add * User: Mikkle * QQ:776329498 * @param $data * @return bool */ static public function start($data=[]){ try{ $data=json_encode($data); $instance = static::instance(); self::clearWorkingStop(); switch (true){ case (self::checkWorking()): Log::notice("Work service is Running!!"); return "CycleWork service is Running!!"; break; case (self::checkCommandRun()): $instance->redis->hSet("cycle_list",$instance->listName,$data); Log::notice("Command service start work!!"); $instance->runWorker(); break; default: Log::notice("Command service No away!!"); return "Command service No away!!"; // $instance->runHandle($data); } return "true"; }catch (Exception $e){ Log::error($e->getMessage()); return false; } } /** * * 當命令行未運行 直接執行 * description add * User: Mikkle * QQ:776329498 */ static public function stop(){ return self::signWorkingStop(); } static public function status(){ return self::checkWorking(); } static public function signWorking($time=20){ self::redis()->set(self::instance()->workerName."_run","true",$time); } static public function checkWorking(){ return self::redis()->get(self::instance()->workerName."_run") ? true :false; } static public function clearWorkingWork(){ self::redis()->hDel("cycle_list",self::instance()->listName); return self::redis()->delete( self::instance()->workerName."_stop"); } static public function signWorkingStop($time=3600*24){ self::redis()->hDel("cycle_list",self::instance()->listName); return self::redis()->set(self::instance()->workerName."_stop","true",$time); } static public function clearWorkingStop(){ return self::redis()->delete( self::instance()->workerName."_stop"); } static public function checkWorkingStop(){ if (!empty(self::instance()->stopTime )){ if ( time()>strtotime( self::instance()->stopTime )){ return true; }else{ return self::redis()->get(self::instance()->workerName."_stop") ? true :false; } } return self::redis()->get(self::instance()->workerName."_stop") ? true :false; } /** * 命令行執行的方法 * Power: Mikkle * Email:776329498@qq.com */ static public function run(){ $instance = static::instance(); try { $redisData = $instance->redis->hGet("cycle_list", $instance->listName); if ($redisData) { $data = json_decode($redisData, true); if ($data) { echo "開始執行循環任務" . PHP_EOL; $instance->pcntlWorker($data); $instance->redis->hDel("cycle_list", $instance->listName); } else { $instance->clearWorker(); } } else { $instance->clearWorker(); echo "未檢測到循環任務" . PHP_EOL; } } catch (Exception $e) { Log::error($e->getMessage()); echo($e->getMessage()); } } /** * 檢測命令行是否執行中 * Power: Mikkle * Email:776329498@qq.com * @return bool */ static public function checkCommandRun(){ return self::redis()->get("command") ? true :false; } public function getError(){ if (is_array($this->error )){ return json_encode( $this->error ); } return $this->error; } /* * 檢查是注重某些值是非為空 */ protected function checkArrayValueEmpty($array,$value,$error=true){ switch (true){ case (empty($array)||!is_array($array)): if ($error==true){ $this->addError("要檢測的數據不存在或者非數組"); } return false; break; case (is_array($value)): foreach ($value as $item){ if (!isset($array[$item]) || (empty($array[$item]) && $array[$item]!==0)){ if ($error==true) { $this->addError("要檢測的數組數據有不存在鍵值{$item}"); } return false; } } break; case (is_string($value)): if (!isset($array[$value]) || empty($array[$value] && $array[$value]!==0)){ if ($error==true) { $this->addError("要檢測的數組數據有不存在鍵值{$value}"); } return false; } break; default: } return true; } public function addError($error){ $this->error = is_string($error) ? $error : json_encode($error); } protected function saveRunLog($result,$data){ try{ $operateData = [ "class" => $this->workerName, "args" => json_encode($data), "result"=> $result ? "true":"false", "error" => $this->error ? $this->getError() : null, "time" => Time::getDefaultTimeString(), ]; Db::connect($this->connect)->table($this->tableName)->insert($operateData); }catch (Exception $e){ Log::error($e->getMessage()); } } protected function sleep($time=1){ if ($time<=10){ sleep(sleep($time)); }else{ $ci = $time/10; for($i=0; $i<$ci;$i++){ self::signWorking(); echo "已睡眠 10 秒"; sleep(10); } sleep(sleep($time%10)); } } /** * title 分進程 * description pcntlWorker * User: Mikkle * QQ:776329498 * @param $data * @param string $action */ protected function pcntlWorker($data,$action = "runHandle") { try{ // 通過pcntl得到一個子進程的PID $pid = pcntl_fork(); if ($pid == -1) { // 錯誤處理:創建子進程失敗時返回-1. die ('could not fork'); } else if ($pid) { // 父進程邏輯 // 等待子進程中斷,防止子進程成為僵尸進程。 // WNOHANG為非阻塞進程,具體請查閱pcntl_wait PHP官方文檔 pcntl_wait($status, WNOHANG); } else { // 子進程邏輯 $pid_2 = pcntl_fork(); if ($pid_2 == -1) { // 錯誤處理:創建子進程失敗時返回-1. die ('could not fork'); } else if ($pid_2) { // 父進程邏輯 echo "父進程邏輯開始" . PHP_EOL; // 等待子進程中斷,防止子進程成為僵尸進程。 // WNOHANG為非阻塞進程,具體請查閱pcntl_wait PHP官方文檔 pcntl_wait($status, WNOHANG); echo "父進程邏輯結束" . PHP_EOL; } else { // 子進程邏輯 echo "子進程邏輯開始" . PHP_EOL; $this->$action( $data ); echo "子進程邏輯結束" . PHP_EOL; $this->pcntlKill(); } $this->pcntlKill(); } }catch (Exception $e){ Log::error($e->getMessage()); } } /** * Kill子進程 * Power: Mikkle * Email:776329498@qq.com */ protected function pcntlKill(){ // 為避免僵尸進程,當子進程結束后,手動殺死進程 if (function_exists("posix_kill")) { posix_kill(getmypid(), SIGTERM); } system('kill -9 ' . getmypid()); exit (); } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看