From 9dfbd2573f7e491c9f8863420575a65104c7e2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 14 Aug 2018 10:33:36 +0800 Subject: [PATCH 01/48] =?UTF-8?q?=E6=8F=90=E5=8F=96=E5=B0=81=E8=A3=85Bean?= =?UTF-8?q?=E7=B1=BB=E7=BC=93=E5=AD=98=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.php | 4 ++-- src/Bean/BeanFactory.php | 12 ++++++++-- src/Listener/WorkerInit.php | 4 ++-- src/Log/ErrorLog.php | 4 ++-- src/Log/Logger.php | 4 ++-- src/Util/Imi.php | 48 +++++++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/App.php b/src/App.php index 93bf786110..8cd523a3c6 100644 --- a/src/App.php +++ b/src/App.php @@ -15,6 +15,7 @@ use Imi\Server\Http\Server; use Imi\Main\Helper as MainHelper; use Imi\Util\CoroutineChannelManager; +use Imi\Util\Imi; abstract class App { @@ -87,8 +88,7 @@ private static function initFramework() private static function clearBeanCache() { // 清除框架 Bean类 缓存 - $path = Config::get('@app.beanClassCache', sys_get_temp_dir()); - $path = File::path($path, 'imiBeanCache', 'imi'); + $path = Imi::getImiClassCachePath(); foreach (File::enum($path) as $file) { if (is_file($file)) diff --git a/src/Bean/BeanFactory.php b/src/Bean/BeanFactory.php index 2dbcdaca31..2582fb7176 100644 --- a/src/Bean/BeanFactory.php +++ b/src/Bean/BeanFactory.php @@ -7,6 +7,7 @@ use Imi\RequestContext; use Imi\Util\ClassObject; use Imi\Bean\Parser\BeanParser; +use Imi\Util\Imi; abstract class BeanFactory { @@ -49,8 +50,15 @@ public static function newInstance($class, ...$args) */ private static function getCacheFileName($className) { - $path = Config::get('@app.beanClassCache', sys_get_temp_dir()); - return File::path($path, 'imiBeanCache', Worker::getWorkerID() ?? 'imi', str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'); + $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; + if(null === ($workerID = Worker::getWorkerID())) + { + return Imi::getImiClassCachePath($fileName); + } + else + { + return Imi::getWorkerClassCachePathByWorkerID($workerID, $fileName); + } } /** diff --git a/src/Listener/WorkerInit.php b/src/Listener/WorkerInit.php index 87fc310baa..0112e5cffe 100644 --- a/src/Listener/WorkerInit.php +++ b/src/Listener/WorkerInit.php @@ -15,6 +15,7 @@ use Imi\Util\CoroutineChannelManager; use Imi\Server\Event\Param\WorkerStartEventParam; use Imi\Server\Event\Listener\IWorkerStartEventListener; +use Imi\Util\Imi; /** * @Listener(eventName="IMI.MAIN_SERVER.WORKER.START",priority=PHP_INT_MAX) @@ -31,8 +32,7 @@ public function handle(WorkerStartEventParam $e) $GLOBALS['WORKER_START_END_RESUME_COIDS'] = []; // 清除当前 worker 进程的 Bean 类缓存 - $path = Config::get('@app.beanClassCache', sys_get_temp_dir()); - $path = File::path($path, 'imiBeanCache', $e->server->getSwooleServer()->worker_id); + $path = Imi::getWorkerClassCachePathByWorkerID($e->server->getSwooleServer()->worker_id); foreach (File::enum($path) as $file) { if (is_file($file)) diff --git a/src/Log/ErrorLog.php b/src/Log/ErrorLog.php index 48d2202ced..b9b68e7b0b 100644 --- a/src/Log/ErrorLog.php +++ b/src/Log/ErrorLog.php @@ -9,6 +9,7 @@ use Imi\RequestContext; use Imi\Pool\PoolManager; use Imi\Bean\Annotation\Bean; +use Imi\Util\Imi; /** * @Bean("ErrorLog") @@ -30,8 +31,7 @@ class ErrorLog public function register() { error_reporting(0); - $path = Config::get('@app.beanClassCache', sys_get_temp_dir()); - $this->beanCacheFilePath = File::path($path, 'imiBeanCache', 'imi', str_replace('\\', DIRECTORY_SEPARATOR, __CLASS__) . '.php'); + $this->beanCacheFilePath = Imi::getImiClassCachePath(str_replace('\\', DIRECTORY_SEPARATOR, __CLASS__) . '.php'); register_shutdown_function([$this, 'onShutdown']); set_error_handler([$this, 'onError']); } diff --git a/src/Log/Logger.php b/src/Log/Logger.php index 10cc413ac1..8067d57229 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -10,6 +10,7 @@ use Imi\Bean\BeanFactory; use Psr\Log\AbstractLogger; use Imi\Bean\Annotation\Bean; +use Imi\Util\Imi; /** * @Bean("Logger") @@ -92,8 +93,7 @@ public function __init() { $this->handlers[] = BeanFactory::newInstance($handlerOption['class'], $handlerOption['options']); } - $path = Config::get('@app.beanClassCache', sys_get_temp_dir()); - $this->beanCacheFilePath = File::path($path, 'imiBeanCache', '%s', str_replace('\\', DIRECTORY_SEPARATOR, __CLASS__) . '.php'); + $this->beanCacheFilePath = Imi::getBeanClassCachePath('%s', str_replace('\\', DIRECTORY_SEPARATOR, __CLASS__) . '.php'); if($this->autoSaveInterval > 0) { $this->timerID = swoole_timer_tick($this->autoSaveInterval * 1000, function(){ diff --git a/src/Util/Imi.php b/src/Util/Imi.php index 1d3c2f6d21..d046d91f0f 100644 --- a/src/Util/Imi.php +++ b/src/Util/Imi.php @@ -2,6 +2,8 @@ namespace Imi\Util; use Imi\App; +use Imi\Config; +use Imi\Worker; use Imi\Main\Helper; use Imi\Bean\BeanProxy; use Imi\Bean\Parser\BeanParser; @@ -220,4 +222,50 @@ public static function getClassPropertyValue($className, $propertyName) } return $value; } + + /** + * 获取Bean类缓存根目录 + * + * @param string ...$paths + * @return string + */ + public static function getBeanClassCachePath(...$paths) + { + return File::path(Config::get('@app.beanClassCache', sys_get_temp_dir()), 'imiBeanCache', str_replace('\\', '-', App::getNamespace()), ...$paths); + } + + /** + * 获取IMI框架Bean类缓存目录 + * + * @param string ...$paths + * @return string + */ + public static function getImiClassCachePath(...$paths) + { + return File::path(static::getBeanClassCachePath(), 'imi', ...$paths); + } + + /** + * 获取Worker进程Bean类缓存目录 + * + * @param string ...$paths + * @return string + */ + public static function getWorkerClassCachePath(...$paths) + { + return static::getWorkerClassCachePathByWorkerID(Worker::getWorkerID(), ...$paths); + } + + /** + * 获取Worker进程Bean类缓存目录,手动传入workerID + * + * @param int $workerID + * @param string ...$paths + * @return string + */ + public static function getWorkerClassCachePathByWorkerID($workerID, ...$paths) + { + return File::path(static::getBeanClassCachePath(), $workerID, ...$paths); + } + } \ No newline at end of file From 092d5e082a4c4120beadb614bc66b63b0a9a3a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 14 Aug 2018 12:44:18 +0800 Subject: [PATCH 02/48] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=94=81=E5=AE=9E=E7=8E=B0=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E5=AE=9E=E4=BE=8B=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HotUpdate/HotUpdateProcess.php | 2 +- src/Process/Annotation/Process.php | 7 + .../Exception/ProcessAlreadyRunException.php | 7 + src/Process/ProcessManager.php | 138 +++++++++++++++++- 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 src/Process/Exception/ProcessAlreadyRunException.php diff --git a/src/HotUpdate/HotUpdateProcess.php b/src/HotUpdate/HotUpdateProcess.php index 5d71247a14..4d1415fbe0 100644 --- a/src/HotUpdate/HotUpdateProcess.php +++ b/src/HotUpdate/HotUpdateProcess.php @@ -12,7 +12,7 @@ /** * @Bean("hotUpdate") - * @Process("hotUpdate") + * @Process(name="hotUpdate", unique=true) */ class HotUpdateProcess extends BaseProcess { diff --git a/src/Process/Annotation/Process.php b/src/Process/Annotation/Process.php index b1107ef6b6..ae5977b824 100644 --- a/src/Process/Annotation/Process.php +++ b/src/Process/Annotation/Process.php @@ -36,4 +36,11 @@ class Process extends Base * @var int */ public $pipeType = 2; + + /** + * 该进程是否只允许存在一个实例 + * + * @var boolean + */ + public $unique = false; } \ No newline at end of file diff --git a/src/Process/Exception/ProcessAlreadyRunException.php b/src/Process/Exception/ProcessAlreadyRunException.php new file mode 100644 index 0000000000..4337e340d3 --- /dev/null +++ b/src/Process/Exception/ProcessAlreadyRunException.php @@ -0,0 +1,7 @@ +getProcess($name); + if(null === $processOption) + { + return null; + } + if($processOption['Process']->unique && static::isRunning($name)) + { + throw new ProcessAlreadyRunException(sprintf('process %s already run', $name)); + } if(null === $redirectStdinStdout) { $redirectStdinStdout = $processOption['Process']->redirectStdinStdout; @@ -33,9 +51,16 @@ public static function create($name, $args = [], $redirectStdinStdout = null, $p $pipeType = $processOption['Process']->pipeType; } $processInstance = BeanFactory::newInstance($processOption['className'], $args); - $process = new \Swoole\Process(function(\Swoole\Process $swooleProcess) use($processInstance, $name){ + $process = new \Swoole\Process(function(\Swoole\Process $swooleProcess) use($processInstance, $name, $processOption){ // 设置进程名称 $swooleProcess->name($name); + if($processOption['Process']->unique) + { + if(!static::lockProcess($name)) + { + throw new \RuntimeException('lock process lock file error'); + } + } // 进程开始事件 Event::trigger('IMI.PROCESS.BEGIN', [ 'name' => $name, @@ -43,6 +68,12 @@ public static function create($name, $args = [], $redirectStdinStdout = null, $p ]); // 执行任务 call_user_func([$processInstance, 'run'], $swooleProcess); + swoole_event_wait(); + var_dump('over:' . $name); + if($processOption['Process']->unique) + { + static::unlockProcess($name); + } // 进程结束事件 Event::trigger('IMI.PROCESS.END', [ 'name' => $name, @@ -52,6 +83,44 @@ public static function create($name, $args = [], $redirectStdinStdout = null, $p return $process; } + /** + * 进程是否已在运行,只有unique为true时有效 + * + * @param string $name + * @return boolean + */ + public static function isRunning($name) + { + $processOption = ProcessParser::getInstance()->getProcess($name); + if(null === $processOption) + { + return false; + } + if(!$processOption['Process']->unique) + { + return false; + } + $fileName = static::getLockFileName($name); + if(!is_file($fileName)) + { + return false; + } + $fp = fopen($fileName, 'w+'); + if(false === $fp) + { + return false; + } + if(!flock($fp, LOCK_EX | LOCK_NB)) + { + fclose($fp); + return true; + } + flock($fp, LOCK_UN); + fclose($fp); + unlink($fileName); + return false; + } + /** * 运行进程,同步阻塞等待进程执行返回 * 不返回\Swoole\Process对象实例 @@ -103,4 +172,67 @@ public static function coRun($name, $args = [], $redirectStdinStdout = null, $pi static::run($name, $args, $redirectStdinStdout, $pipeType); }); } + + /** + * 锁定进程,实现unique + * + * @param string $name + * @return boolean + */ + private static function lockProcess($name) + { + $fileName = static::getLockFileName($name); + $fp = fopen($fileName, 'w+'); + if(false === $fp) + { + return false; + } + if(!flock($fp, LOCK_EX | LOCK_NB)) + { + fclose($fp); + return false; + } + static::$lockMap[$name] = [ + 'fileName' => $fileName, + 'fp' => $fp, + ]; + return true; + } + + /** + * 解锁进程,实现unique + * + * @param string $name + * @return boolean + */ + private static function unlockProcess($name) + { + if(!isset(static::$lockMap[$name])) + { + return false; + } + if(flock(static::$lockMap[$name]['fp'], LOCK_UN) && fclose(static::$lockMap[$name]['fp'])) + { + unlink(static::$lockMap[$name]['fileName']); + unset(static::$lockMap[$name]); + return true; + } + return false; + } + + /** + * 获取文件锁的文件名 + * + * @param string $name + * @return string + */ + private static function getLockFileName($name) + { + $path = File::path(sys_get_temp_dir(), str_replace('\\', '-', App::getNamespace()), 'processLock'); + if(!is_dir($path)) + { + File::createDir($path); + } + return File::path($path, $name . '.lock'); + } } \ No newline at end of file From 28bbe8a6eeedae276a74f16e92dd4d0063280242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 14 Aug 2018 12:45:36 +0800 Subject: [PATCH 03/48] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=83=AD=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=BF=9B=E7=A8=8B=E5=90=AF=E5=8A=A8=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HotUpdate/HotUpdateProcess.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HotUpdate/HotUpdateProcess.php b/src/HotUpdate/HotUpdateProcess.php index 4d1415fbe0..46a521b3b4 100644 --- a/src/HotUpdate/HotUpdateProcess.php +++ b/src/HotUpdate/HotUpdateProcess.php @@ -65,6 +65,7 @@ public function run(\Swoole\Process $process) ]; } go(function(){ + echo 'hotUpdate process start', PHP_EOL; $monitor = BeanFactory::newInstance($this->monitorClass, array_merge($this->defaultPath, $this->includePaths), $this->excludePaths); $reloadCmd = 'php ' . $_SERVER['argv'][0] . ' server/reload'; if(null !== ($appNamespace = Args::get('appNamespace'))) From 198811da29d25e95cefe9b15804673ec580f0c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 14 Aug 2018 13:35:02 +0800 Subject: [PATCH 04/48] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Process/ProcessManager.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Process/ProcessManager.php b/src/Process/ProcessManager.php index 6986618964..4f36dbfd96 100644 --- a/src/Process/ProcessManager.php +++ b/src/Process/ProcessManager.php @@ -69,7 +69,6 @@ public static function create($name, $args = [], $redirectStdinStdout = null, $p // 执行任务 call_user_func([$processInstance, 'run'], $swooleProcess); swoole_event_wait(); - var_dump('over:' . $name); if($processOption['Process']->unique) { static::unlockProcess($name); From 872dfe93dc31d9d67c8f4aeb10dfe4ddde65dc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 15 Aug 2018 11:21:27 +0800 Subject: [PATCH 05/48] =?UTF-8?q?=E4=BC=98=E5=8C=96Result->get()=E3=80=81R?= =?UTF-8?q?esult->getArray()=E5=BD=93=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E6=97=B6=E8=BF=94=E5=9B=9Enull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Db/Query/Result.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Db/Query/Result.php b/src/Db/Query/Result.php index d4e6fa689b..5f0d922e92 100644 --- a/src/Db/Query/Result.php +++ b/src/Db/Query/Result.php @@ -76,9 +76,9 @@ public function getAffectedRows() } /** - * 返回一行数据,数组或对象 + * 返回一行数据,数组或对象,失败返回null * @param string $className 实体类名,为null则返回数组 - * @return mixed + * @return mixed|null */ public function get($className = null) { @@ -87,6 +87,10 @@ public function get($className = null) throw new \RuntimeException('Result is not success!'); } $result = $this->statement->fetch(); + if(false === $result) + { + return null; + } if(null === $className) { @@ -115,9 +119,9 @@ public function get($className = null) } /** - * 返回数组 + * 返回数组,失败返回null * @param string $className 实体类名,为null则数组每个成员为数组 - * @return array + * @return array|null */ public function getArray($className = null) { @@ -126,6 +130,10 @@ public function getArray($className = null) throw new \RuntimeException('Result is not success!'); } $result = $this->statement->fetchAll(); + if(false === $result) + { + return null; + } if(null === $className) { From f21578ec12cc2acabf409b0a52bff4188d4381f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 15 Aug 2018 15:34:25 +0800 Subject: [PATCH 06/48] =?UTF-8?q?=E5=B0=81=E8=A3=85=E6=8F=90=E5=8F=96?= =?UTF-8?q?=E8=8E=B7=E5=8F=96imi=E5=91=BD=E4=BB=A4=E8=A1=8C=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HotUpdate/HotUpdateProcess.php | 8 ++------ src/Process/ProcessManager.php | 3 ++- src/Util/Imi.php | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/HotUpdate/HotUpdateProcess.php b/src/HotUpdate/HotUpdateProcess.php index 46a521b3b4..90d1af9c28 100644 --- a/src/HotUpdate/HotUpdateProcess.php +++ b/src/HotUpdate/HotUpdateProcess.php @@ -8,7 +8,6 @@ use Imi\Process\BaseProcess; use Imi\Bean\Annotation\Bean; use Imi\Process\Annotation\Process; -use Imi\Util\Args; /** * @Bean("hotUpdate") @@ -67,11 +66,8 @@ public function run(\Swoole\Process $process) go(function(){ echo 'hotUpdate process start', PHP_EOL; $monitor = BeanFactory::newInstance($this->monitorClass, array_merge($this->defaultPath, $this->includePaths), $this->excludePaths); - $reloadCmd = 'php ' . $_SERVER['argv'][0] . ' server/reload'; - if(null !== ($appNamespace = Args::get('appNamespace'))) - { - $reloadCmd .= ' -appNamespace "' . $appNamespace . '"'; - } + + $reloadCmd = Imi::getImiCmd('server', 'reload'); $time = 0; while(true) { diff --git a/src/Process/ProcessManager.php b/src/Process/ProcessManager.php index 4f36dbfd96..84c11f3ffc 100644 --- a/src/Process/ProcessManager.php +++ b/src/Process/ProcessManager.php @@ -7,6 +7,7 @@ use Imi\Bean\BeanFactory; use Imi\Process\Parser\ProcessParser; use Imi\Process\Exception\ProcessAlreadyRunException; +use Imi\Util\Imi; /** * 进程管理类 @@ -138,7 +139,7 @@ public static function isRunning($name) */ public static function run($name, $args = [], $redirectStdinStdout = null, $pipeType = null) { - $cmd = 'php ' . $_SERVER['argv'][0] . ' process/start -name ' . $name; + $cmd = Imi::getImiCmd('process', 'start') . ' -name ' . $name; if(null !== $redirectStdinStdout) { $cmd .= ' -redirectStdinStdout ' . $redirectStdinStdout; diff --git a/src/Util/Imi.php b/src/Util/Imi.php index d046d91f0f..747bc4f733 100644 --- a/src/Util/Imi.php +++ b/src/Util/Imi.php @@ -4,6 +4,7 @@ use Imi\App; use Imi\Config; use Imi\Worker; +use Imi\Util\Args; use Imi\Main\Helper; use Imi\Bean\BeanProxy; use Imi\Bean\Parser\BeanParser; @@ -268,4 +269,20 @@ public static function getWorkerClassCachePathByWorkerID($workerID, ...$paths) return File::path(static::getBeanClassCachePath(), $workerID, ...$paths); } + /** + * 获取imi命令行 + * + * @param string $toolName 工具名,如server + * @param string $operation 操作名,如start + * @return string + */ + public static function getImiCmd($toolName, $operation) + { + $cmd = 'php ' . $_SERVER['argv'][0] . ' ' . $toolName . '/' . $operation; + if(null !== ($appNamespace = Args::get('appNamespace'))) + { + $cmd .= ' -appNamespace "' . $appNamespace . '"'; + } + return $cmd; + } } \ No newline at end of file From 3b519258a59cb78a93e7b1f6b9bf587c700b7bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 15 Aug 2018 16:45:34 +0800 Subject: [PATCH 07/48] =?UTF-8?q?=E8=B0=83=E6=95=B4=EF=BC=9AIMI.INITED?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=B8=AD=E5=AF=B9=E9=A1=B9=E7=9B=AE=E7=B1=BB?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E6=89=AB=E6=8F=8F=EF=BC=8C=E7=83=AD=E9=87=8D?= =?UTF-8?q?=E5=90=AF=E4=BB=85=E5=AF=B9=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=B1=BB?= =?UTF-8?q?=E6=9C=89=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tool/Listener/Init.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Tool/Listener/Init.php b/src/Tool/Listener/Init.php index 67464c39f2..1661ec35ee 100644 --- a/src/Tool/Listener/Init.php +++ b/src/Tool/Listener/Init.php @@ -45,11 +45,6 @@ public function handle(EventParam $e) // 获取回调 $callable = ToolParser::getInstance()->getCallable($tool, $operation); if(null === $callable) - { - Annotation::getInstance()->init([Helper::getMain(App::getNamespace())]); - } - $callable = ToolParser::getInstance()->getCallable($tool, $operation); - if(null === $callable) { throw new \RuntimeException(sprintf('tool %s does not exists!', $_SERVER['argv'][1])); } @@ -111,6 +106,7 @@ public function handle(EventParam $e) */ private function init() { + Annotation::getInstance()->init([Helper::getMain(App::getNamespace())]); RequestContext::create(); // 获取配置 $pools = $caches = []; From df6c38008fe3b44df87344310089574f67c27643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 15 Aug 2018 16:57:26 +0800 Subject: [PATCH 08/48] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E8=BF=9B=E7=A8=8B=E8=BF=90=E8=A1=8C=E6=97=B6=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E8=BF=9E=E6=8E=A5=E6=B1=A0=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Process/ProcessManager.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Process/ProcessManager.php b/src/Process/ProcessManager.php index 84c11f3ffc..13417a07ef 100644 --- a/src/Process/ProcessManager.php +++ b/src/Process/ProcessManager.php @@ -62,6 +62,7 @@ public static function create($name, $args = [], $redirectStdinStdout = null, $p throw new \RuntimeException('lock process lock file error'); } } + App::initWorker(); // 进程开始事件 Event::trigger('IMI.PROCESS.BEGIN', [ 'name' => $name, From 22bf4e3968b61b2d85223587d214cb757ea5c2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 15 Aug 2018 16:58:24 +0800 Subject: [PATCH 09/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=83=AD=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=BF=9B=E7=A8=8B=E5=90=AF=E5=8A=A8=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HotUpdate/HotUpdateProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HotUpdate/HotUpdateProcess.php b/src/HotUpdate/HotUpdateProcess.php index 90d1af9c28..fe3f9616bf 100644 --- a/src/HotUpdate/HotUpdateProcess.php +++ b/src/HotUpdate/HotUpdateProcess.php @@ -64,7 +64,7 @@ public function run(\Swoole\Process $process) ]; } go(function(){ - echo 'hotUpdate process start', PHP_EOL; + echo 'Process [hotUpdate] start', PHP_EOL; $monitor = BeanFactory::newInstance($this->monitorClass, array_merge($this->defaultPath, $this->includePaths), $this->excludePaths); $reloadCmd = Imi::getImiCmd('server', 'reload'); From c0a3f4f0ca82bcf444cb23acae43393d279ec200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Thu, 16 Aug 2018 10:40:12 +0800 Subject: [PATCH 10/48] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=BC=98=E5=8C=96BeanF?= =?UTF-8?q?actory=E5=AE=9E=E4=BE=8B=E5=8C=96=E7=B1=BB=E6=97=B6=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Bean/BeanFactory.php | 52 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/src/Bean/BeanFactory.php b/src/Bean/BeanFactory.php index 2582fb7176..f8b29fa473 100644 --- a/src/Bean/BeanFactory.php +++ b/src/Bean/BeanFactory.php @@ -121,11 +121,14 @@ private static function getMethodsTpl($ref, $class) $tpl .= <<name}({$paramsTpls['define']}){$methodReturnType} { - \$__args__ = [{$paramsTpls['args']}];{$paramsTpls['args_variadic']} + \$__args__ = func_get_args(); + {$paramsTpls['set_args']} return \$this->beanProxy->call( '{$method->name}', function({$paramsTpls['define']}){ - return parent::{$method->name}({$paramsTpls['call']}); + \$__args__ = func_get_args(); + {$paramsTpls['set_args']} + return parent::{$method->name}(...\$__args__); }, \$__args__ ); @@ -147,10 +150,11 @@ private static function getMethodParamTpls(\ReflectionMethod $method) 'args' => [], 'define' => [], 'call' => [], + 'set_args' => '', ]; - foreach($method->getParameters() as $param) + foreach($method->getParameters() as $i => $param) { - // 数组参数,支持引用传参 + // 数组参数,支持可变传参 if(!$param->isVariadic()) { $result['args'][] = static::getMethodParamArgsTpl($param); @@ -159,8 +163,13 @@ private static function getMethodParamTpls(\ReflectionMethod $method) $result['define'][] = static::getMethodParamDefineTpl($param); // 调用传参 $result['call'][] = static::getMethodParamCallTpl($param); + // 引用传参 + if($param->isPassedByReference()) + { + $result['set_args'] .= '$__args__[' . $i . '] = &$' . $param->name . ';'; + } } - foreach($result as &$item) + foreach($result as $key => &$item) { if(is_array($item)) { @@ -172,23 +181,6 @@ private static function getMethodParamTpls(\ReflectionMethod $method) { $result['call'] = '...func_get_args()'; } - // 可变参数 - if(isset($param) && $param->isVariadic()) - { - $result['args_variadic'] = static::getMethodArgsVariadicTpl($param); - } - else - { - $result['args_variadic'] = ''; - } - $result['args_variadic'] .= <<isVariadic() ? '...' : '') . '$' . $param->name; } - /** - * 获取方法可变参数模版 - * @param \ReflectionParameter $param - * @return string - */ - private static function getMethodArgsVariadicTpl(\ReflectionParameter $param) - { - return <<name} as \$__item__) - { - \$__args__[] = \$__item__; - } -TPL; - } - /** * 获取方法返回值模版 * @param \ReflectionMethod $method From c11df7ec9798bf8d3564c2826125fdce2b205891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 10:47:53 +0800 Subject: [PATCH 11/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=B6=E5=B8=A6=E6=9C=89=E4=B8=8D=E6=83=B3?= =?UTF-8?q?=E5=85=B3=E7=9A=84=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/Model.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index c741839891..71664b528f 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -443,7 +443,10 @@ private static function parseSaveData($data, $object = null) $result = new LazyArrayObject; foreach(ModelManager::getFieldNames($class) as $name) { - $result[$name] = $data[$name]; + if(array_key_exists($name, $data)) + { + $result[$name] = $data[$name]; + } } return $result; } From d524263df03e3608073cba42bac676773837eba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 11:06:48 +0800 Subject: [PATCH 12/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=B6=E6=95=B0=E6=8D=AE=E5=85=88=E8=BD=AC?= =?UTF-8?q?=E4=B8=BA=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/Model.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Model/Model.php b/src/Model/Model.php index 71664b528f..a592bcae24 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -439,6 +439,10 @@ private static function parseSaveData($data, $object = null) { $object = $data; } + if($data instanceof static) + { + $data = $data->toArray(); + } $class = BeanFactory::getObjectClass($object ?? static::class); $result = new LazyArrayObject; foreach(ModelManager::getFieldNames($class) as $name) From d11d58476b4e20628fe0057b6bfa6e1716563484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 13:50:30 +0800 Subject: [PATCH 13/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE=E6=97=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=B8=A4=E7=A7=8D=E5=91=BD=E5=90=8D=E7=9A=84=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/Model.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Model/Model.php b/src/Model/Model.php index a592bcae24..b870cb2cf2 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -451,6 +451,14 @@ private static function parseSaveData($data, $object = null) { $result[$name] = $data[$name]; } + else + { + $fieldName = Text::toCamelName($name); + if(array_key_exists($fieldName, $data)) + { + $result[$name] = $data[$fieldName]; + } + } } return $result; } From 862829b61386a86bdcc17e15678904e55f4cb6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 14:37:12 +0800 Subject: [PATCH 14/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/App.php b/src/App.php index 8cd523a3c6..58d8a04324 100644 --- a/src/App.php +++ b/src/App.php @@ -248,11 +248,15 @@ public static function initWorker() } } } + // 缓存初始化 - $caches = $main->getConfig()['caches'] ?? []; - foreach($caches as $name => $cache) + foreach($appMains as $main) { - CacheManager::addName($name, $cache['handlerClass'], $cache['option']); + $caches = $main->getConfig()['caches'] ?? []; + foreach($caches as $name => $cache) + { + CacheManager::addName($name, $cache['handlerClass'], $cache['option']); + } } } } \ No newline at end of file From 378c409fc2f8f45071b328fdfa623ca0fbb2e730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 14:38:21 +0800 Subject: [PATCH 15/48] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E3=80=81=E7=B1=BB=E6=96=87=E4=BB=B6=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=9B=AE=E5=BD=95=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Util/File.php | 10 ++++------ src/Util/Imi.php | 8 +++++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Util/File.php b/src/Util/File.php index 678eacd422..ad0b5b77f2 100644 --- a/src/Util/File.php +++ b/src/Util/File.php @@ -7,18 +7,16 @@ abstract class File /** * 枚举文件 * @param string $dirPath - * @return \RecursiveIterator + * @return \Iterator */ public static function enum($dirPath) { if (!is_dir($dirPath)) { - return; + return new \ArrayIterator([]); } - $iterator = new \RecursiveDirectoryIterator($dirPath); + $iterator = new \RecursiveDirectoryIterator($dirPath, \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS); $files = new \RecursiveIteratorIterator($iterator); - foreach ($files as $file) { - yield $file; - } + return $files; } /** diff --git a/src/Util/Imi.php b/src/Util/Imi.php index 747bc4f733..0b3753156b 100644 --- a/src/Util/Imi.php +++ b/src/Util/Imi.php @@ -232,7 +232,13 @@ public static function getClassPropertyValue($className, $propertyName) */ public static function getBeanClassCachePath(...$paths) { - return File::path(Config::get('@app.beanClassCache', sys_get_temp_dir()), 'imiBeanCache', str_replace('\\', '-', App::getNamespace()), ...$paths); + $main = Helper::getMain(App::getNamespace()); + $beanClassCache = $main->getConfig()['beanClassCache'] ?? null; + if(null === $beanClassCache) + { + $beanClassCache = sys_get_temp_dir(); + } + return File::path($beanClassCache, 'imiBeanCache', str_replace('\\', '-', App::getNamespace()), ...$paths); } /** From 5d13bff6d626b09766cd243847a378eb19dcd5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 14:38:46 +0800 Subject: [PATCH 16/48] =?UTF-8?q?=E8=B0=83=E6=95=B4WorkerStart=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Listener/WorkerInit.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Listener/WorkerInit.php b/src/Listener/WorkerInit.php index 0112e5cffe..2a9cbc315d 100644 --- a/src/Listener/WorkerInit.php +++ b/src/Listener/WorkerInit.php @@ -31,9 +31,13 @@ public function handle(WorkerStartEventParam $e) { $GLOBALS['WORKER_START_END_RESUME_COIDS'] = []; + // 当前进程的 WorkerID 设置 + Worker::setWorkerID($e->server->getSwooleServer()->worker_id); + // 清除当前 worker 进程的 Bean 类缓存 - $path = Imi::getWorkerClassCachePathByWorkerID($e->server->getSwooleServer()->worker_id); - foreach (File::enum($path) as $file) + $path = Imi::getWorkerClassCachePathByWorkerID(Worker::getWorkerID()); + + foreach(File::enum($path) as $file) { if (is_file($file)) { @@ -41,9 +45,6 @@ public function handle(WorkerStartEventParam $e) } } - // 当前进程的 WorkerID 设置 - Worker::setWorkerID($e->server->getSwooleServer()->worker_id); - // 初始化 worker App::initWorker(); } From b765a487fea3355a51e7c9362d35f3b65cf67969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 14:39:32 +0800 Subject: [PATCH 17/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dkv=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E7=B1=BB=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Util/KVStorage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Util/KVStorage.php b/src/Util/KVStorage.php index 639ae963de..2a53490707 100644 --- a/src/Util/KVStorage.php +++ b/src/Util/KVStorage.php @@ -104,7 +104,7 @@ private static function parseObject($object, $isStore = true) else { // 其它 - if(false !== ($index = array_search($object, static::$otherMap))) + if(false !== ($index = array_search($object, static::$otherMap, true))) { return static::$otherToObjectMap[$index]; } From cca1df8d037ac323fe3e6f1471ea32e1a37a6b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Fri, 17 Aug 2018 16:12:03 +0800 Subject: [PATCH 18/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=B8=A6where=E6=9D=A1=E4=BB=B6=E6=9F=90=E4=BA=9B=E6=83=85?= =?UTF-8?q?=E5=86=B5=E5=AD=98=E5=9C=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/Model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index b870cb2cf2..26c3ae04c2 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -416,8 +416,8 @@ private static function parseWhere(IQuery $query, $where) { if(is_array($v)) { - $operation = array_unshift($v); - $query->where($k, $operation, $v[1]); + $operation = array_shift($v); + $query->where($k, $operation, $v[0]); } else { From 3700b68c80b756dda2a1ea217729dae8ffbc53de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Mon, 20 Aug 2018 10:44:17 +0800 Subject: [PATCH 19/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=80=E6=B3=A2?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.php | 5 +---- src/Bean/AnnotationLoader.php | 1 + src/Listener/WorkerInit.php | 5 +---- src/Util/File.php | 12 +++++------- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/App.php b/src/App.php index 58d8a04324..f31a015ee6 100644 --- a/src/App.php +++ b/src/App.php @@ -91,10 +91,7 @@ private static function clearBeanCache() $path = Imi::getImiClassCachePath(); foreach (File::enum($path) as $file) { - if (is_file($file)) - { - unlink($file); - } + unlink($file); } } diff --git a/src/Bean/AnnotationLoader.php b/src/Bean/AnnotationLoader.php index a71e71a3c8..1d290553ea 100644 --- a/src/Bean/AnnotationLoader.php +++ b/src/Bean/AnnotationLoader.php @@ -23,6 +23,7 @@ public function loadModuleAnnotations($namespace, $callback) $pathLength = strlen($path); foreach(File::enumPHPFile($path) as $filePath) { + $filePath = $filePath[0]; $diffPath = substr($filePath, $pathLength); if(isset($diffPath[0]) && DIRECTORY_SEPARATOR === $diffPath[0]) { diff --git a/src/Listener/WorkerInit.php b/src/Listener/WorkerInit.php index 2a9cbc315d..dcee56c3a4 100644 --- a/src/Listener/WorkerInit.php +++ b/src/Listener/WorkerInit.php @@ -39,10 +39,7 @@ public function handle(WorkerStartEventParam $e) foreach(File::enum($path) as $file) { - if (is_file($file)) - { - unlink($file); - } + unlink((string)$file); } // 初始化 worker diff --git a/src/Util/File.php b/src/Util/File.php index ad0b5b77f2..2a46f949e1 100644 --- a/src/Util/File.php +++ b/src/Util/File.php @@ -7,12 +7,12 @@ abstract class File /** * 枚举文件 * @param string $dirPath - * @return \Iterator + * @return \RecursiveIteratorIterator|\ArrayIterator */ public static function enum($dirPath) { if (!is_dir($dirPath)) { - return new \ArrayIterator([]); + return new \ArrayIterator(); } $iterator = new \RecursiveDirectoryIterator($dirPath, \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS); $files = new \RecursiveIteratorIterator($iterator); @@ -22,19 +22,17 @@ public static function enum($dirPath) /** * 枚举php文件 * @param string $dirPath - * @return \RegexIterator + * @return \RegexIterator|ArrayIterator */ public static function enumPHPFile($dirPath) { if (!is_dir($dirPath)) { - return; + return new \ArrayIterator(); } $directory = new \RecursiveDirectoryIterator($dirPath); $iterator = new \RecursiveIteratorIterator($directory); $regex = new \RegexIterator($iterator, '/^.+\.php$/i', \RecursiveRegexIterator::GET_MATCH); - foreach ($regex as $item) { - yield $item[0]; - } + return $regex; } /** From 9485d8dc925647b9f5f19c03b9ed33cba408c476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Mon, 20 Aug 2018 10:47:11 +0800 Subject: [PATCH 20/48] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E4=BF=AE=E5=A4=8DWorke?= =?UTF-8?q?rStart=20+=20Coroutine::writeFile=20+=20=E7=83=AD=E9=87=8D?= =?UTF-8?q?=E5=90=AF=E5=A5=87=E6=80=AA=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Bean/BeanFactory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bean/BeanFactory.php b/src/Bean/BeanFactory.php index f8b29fa473..1bf2178e4c 100644 --- a/src/Bean/BeanFactory.php +++ b/src/Bean/BeanFactory.php @@ -30,7 +30,8 @@ public static function newInstance($class, ...$args) { File::createDir($path); } - File::writeFile($cacheFileName, ' Date: Mon, 20 Aug 2018 13:16:58 +0800 Subject: [PATCH 21/48] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=B1=A0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Process/Annotation/ProcessPool.php | 48 ++++++++++++++ src/Process/BasePoolProcess.php | 20 ++++++ src/Process/IPoolProcess.php | 10 +++ src/Process/Parser/ProcessPoolParser.php | 41 ++++++++++++ src/Process/ProcessPoolManager.php | 79 ++++++++++++++++++++++++ src/Tool/Tools/Process/Process.php | 21 +++++++ 6 files changed, 219 insertions(+) create mode 100644 src/Process/Annotation/ProcessPool.php create mode 100644 src/Process/BasePoolProcess.php create mode 100644 src/Process/IPoolProcess.php create mode 100644 src/Process/Parser/ProcessPoolParser.php create mode 100644 src/Process/ProcessPoolManager.php diff --git a/src/Process/Annotation/ProcessPool.php b/src/Process/Annotation/ProcessPool.php new file mode 100644 index 0000000000..5421663fc7 --- /dev/null +++ b/src/Process/Annotation/ProcessPool.php @@ -0,0 +1,48 @@ +data = $data; + foreach($data as $k => $v) + { + $this->$k = $v; + } + } +} \ No newline at end of file diff --git a/src/Process/IPoolProcess.php b/src/Process/IPoolProcess.php new file mode 100644 index 0000000000..1e63ef73dd --- /dev/null +++ b/src/Process/IPoolProcess.php @@ -0,0 +1,10 @@ +data[$annotation->name])) + { + new \RuntimeException(sprintf('process pool %s is exists', $annotation->name)); + } + $this->data[$annotation->name] = [ + 'className' => $className, + 'ProcessPool' => $annotation, + ]; + } + } + + /** + * 获取processPool信息 + * @param string $name processPool名称 + * @return array + */ + public function getProcessPool($name) + { + return $this->data[$name] ?? null; + } +} \ No newline at end of file diff --git a/src/Process/ProcessPoolManager.php b/src/Process/ProcessPoolManager.php new file mode 100644 index 0000000000..ad9db88cc2 --- /dev/null +++ b/src/Process/ProcessPoolManager.php @@ -0,0 +1,79 @@ +getProcessPool($name); + if(null === $processPoolOption) + { + return null; + } + if(null === $workerNum) + { + $workerNum = $processPoolOption['ProcessPool']->workerNum; + } + if(null === $ipcType) + { + $ipcType = $processPoolOption['ProcessPool']->ipcType; + } + if(null === $msgQueueKey) + { + $msgQueueKey = $processPoolOption['ProcessPool']->msgQueueKey; + } + + $pool = new \Swoole\Process\Pool($workerNum, $ipcType, $msgQueueKey); + + $pool->on('WorkerStart', function ($pool, $workerId) use($name, $processPoolOption, $args) { + $processInstance = BeanFactory::newInstance($processPoolOption['className'], $args); + App::initWorker(); + // 进程开始事件 + Event::trigger('IMI.PROCESS_POOL.PROCESS.BEGIN', [ + 'name' => $name, + 'pool' => $pool, + 'workerId' => $workerId, + ]); + // 执行任务 + call_user_func([$processInstance, 'run'], $pool, $workerId); + swoole_event_wait(); + }); + + $pool->on('WorkerStop', function ($pool, $workerId) use($name) { + // 进程结束事件 + Event::trigger('IMI.PROCESS_POOL.PROCESS.END', [ + 'name' => $name, + 'pool' => $pool, + 'workerId' => $workerId, + ]); + }); + + return $pool; + + } + +} \ No newline at end of file diff --git a/src/Tool/Tools/Process/Process.php b/src/Tool/Tools/Process/Process.php index 5a6a865f02..d6cc92c4dd 100644 --- a/src/Tool/Tools/Process/Process.php +++ b/src/Tool/Tools/Process/Process.php @@ -8,6 +8,7 @@ use Imi\Tool\Annotation\Tool; use Imi\Process\ProcessManager; use Imi\Tool\Annotation\Operation; +use Imi\Process\ProcessPoolManager; /** * @Tool("process") @@ -34,4 +35,24 @@ public function start($name, $redirectStdinStdout, $pipeType) $result = \swoole_process::wait(true); echo 'process exit! pid:', $result['pid'], ', code:', $result['code'], ', signal:', $result['signal'], PHP_EOL; } + + /** + * 开启一个进程池,可以任意添加参数 + * + * @Operation("pool") + * + * @Arg(name="name", type=ArgType::STRING, required=true, comments="进程池名称,通过@ProcessPool注解定义") + * @Arg(name="worker", type=ArgType::INT, default=null, comments="进程数量,不传则根据注解配置设定") + * @Arg(name="ipcType", type=ArgType::INT, default=null, comments="进程间通信的模式,默认为0表示不使用任何进程间通信特性,不传则根据注解配置设定") + * @Arg(name="msgQueueKey", type=ArgType::STRING, default=null, comments="消息队列键,不传则根据注解配置设定") + * + * @return void + */ + public function pool($name, $worker, $ipcType, $msgQueueKey) + { + App::initWorker(); + $args = Args::get(); + $processPool = ProcessPoolManager::create($name, $worker, $args, $ipcType, $msgQueueKey); + $processPool->start(); + } } \ No newline at end of file From 77c2647782a748ca7083bb36f53a80766722107f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Mon, 20 Aug 2018 13:29:37 +0800 Subject: [PATCH 22/48] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=BC=A0=E5=85=A5=E8=BF=9B=E7=A8=8B=E6=B1=A0=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Process/IPoolProcess.php | 14 +++++++++++++- src/Process/ProcessPoolManager.php | 14 +++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Process/IPoolProcess.php b/src/Process/IPoolProcess.php index 1e63ef73dd..b64d3d8034 100644 --- a/src/Process/IPoolProcess.php +++ b/src/Process/IPoolProcess.php @@ -6,5 +6,17 @@ */ interface IPoolProcess { - public function run(\Swoole\Process\Pool $pool, int $workerId); + /** + * 进程执行 + * + * @param \Swoole\Process\Pool $pool + * @param integer $workerId + * @param string $name + * @param int $workerNum + * @param array $args + * @param int $ipcType + * @param string $msgQueueKey + * @return void + */ + public function run(\Swoole\Process\Pool $pool, int $workerId, $name, $workerNum, $args, $ipcType, $msgQueueKey); } \ No newline at end of file diff --git a/src/Process/ProcessPoolManager.php b/src/Process/ProcessPoolManager.php index ad9db88cc2..fc986bdf14 100644 --- a/src/Process/ProcessPoolManager.php +++ b/src/Process/ProcessPoolManager.php @@ -49,7 +49,7 @@ public static function create($name, $workerNum = null, $args = [], $ipcType = 0 $pool = new \Swoole\Process\Pool($workerNum, $ipcType, $msgQueueKey); - $pool->on('WorkerStart', function ($pool, $workerId) use($name, $processPoolOption, $args) { + $pool->on('WorkerStart', function ($pool, $workerId) use($name, $workerNum, $args, $ipcType, $msgQueueKey, $processPoolOption) { $processInstance = BeanFactory::newInstance($processPoolOption['className'], $args); App::initWorker(); // 进程开始事件 @@ -57,18 +57,26 @@ public static function create($name, $workerNum = null, $args = [], $ipcType = 0 'name' => $name, 'pool' => $pool, 'workerId' => $workerId, + 'workerNum' => $workerNum, + 'args' => $args, + 'ipcType' => $ipcType, + 'msgQueueKey' => $msgQueueKey, ]); // 执行任务 - call_user_func([$processInstance, 'run'], $pool, $workerId); + call_user_func([$processInstance, 'run'], $pool, $workerId, $name, $workerNum, $args, $ipcType, $msgQueueKey); swoole_event_wait(); }); - $pool->on('WorkerStop', function ($pool, $workerId) use($name) { + $pool->on('WorkerStop', function ($pool, $workerId) use($name, $workerNum, $args, $ipcType, $msgQueueKey) { // 进程结束事件 Event::trigger('IMI.PROCESS_POOL.PROCESS.END', [ 'name' => $name, 'pool' => $pool, 'workerId' => $workerId, + 'workerNum' => $workerNum, + 'args' => $args, + 'ipcType' => $ipcType, + 'msgQueueKey' => $msgQueueKey, ]); }); From e6a5d174addc8a54a4333e67c97f10c2f68eef91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 08:56:52 +0800 Subject: [PATCH 23/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E6=9C=AA=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/Model.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 26c3ae04c2..587ae9f5c8 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -2,12 +2,13 @@ namespace Imi\Model; use Imi\Db\Db; +use Imi\Util\Text; +use Imi\Event\Event; use Imi\Bean\BeanFactory; +use Imi\Util\LazyArrayObject; use Imi\Model\Event\ModelEvents; use Imi\Db\Query\Interfaces\IQuery; use Imi\Db\Query\Interfaces\IResult; -use Imi\Util\LazyArrayObject; -use Imi\Event\Event; /** * 常用的数据库模型 From 5d9f3f74726ac1f82d60f350c23342f9ca54d6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 08:57:18 +0800 Subject: [PATCH 24/48] =?UTF-8?q?=E4=B8=BACoroutineChannelManager::pop()?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=A2=9E=E5=8A=A0$timeout=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Util/CoroutineChannelManager.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Util/CoroutineChannelManager.php b/src/Util/CoroutineChannelManager.php index ecaa69b4e6..580db217d4 100644 --- a/src/Util/CoroutineChannelManager.php +++ b/src/Util/CoroutineChannelManager.php @@ -67,11 +67,12 @@ public static function push(string $name, $data) * 当通道内有数据时自动将数据弹出并还原为PHP变量 * 当通道内没有任何数据时pop会失败并返回false * @param string $name + * @param float $timeout * @return mixed */ - public static function pop(string $name) + public static function pop(string $name, $timeout = 0) { - return static::getInstance($name)->pop(); + return static::getInstance($name)->pop($timeout); } /** From 99e9c268caed87b54a11ab5a32ff4405e2e447c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 09:10:03 +0800 Subject: [PATCH 25/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8nullable=E4=B8=BA=E5=8F=8D=E5=80=BC?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tool/Tools/Generate/Model/ModelGenerate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tool/Tools/Generate/Model/ModelGenerate.php b/src/Tool/Tools/Generate/Model/ModelGenerate.php index 7abe916ed9..4e9a8285c3 100644 --- a/src/Tool/Tools/Generate/Model/ModelGenerate.php +++ b/src/Tool/Tools/Generate/Model/ModelGenerate.php @@ -136,7 +136,7 @@ private function parseFields($fields, &$data) 'phpType' => $this->dbFieldTypeToPhp($typeName), 'length' => $length, 'accuracy' => $accuracy, - 'nullable' => $field['Null'] !== 'YES', + 'nullable' => $field['Null'] === 'YES', 'default' => $field['Default'], 'isPrimaryKey' => $isPk, 'primaryKeyIndex' => $isPk ? $idCount : -1, From 29a7ba98a5bd00a68c24076c9956210e14ea790a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 09:10:45 +0800 Subject: [PATCH 26/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=97=B6null=E5=80=BC=E5=88=A4=E5=AE=9A?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/Model.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 587ae9f5c8..fee8ccd479 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -446,20 +446,29 @@ private static function parseSaveData($data, $object = null) } $class = BeanFactory::getObjectClass($object ?? static::class); $result = new LazyArrayObject; - foreach(ModelManager::getFieldNames($class) as $name) + foreach(ModelManager::getFields($class) as $name => $column) { if(array_key_exists($name, $data)) { - $result[$name] = $data[$name]; + $value = $data[$name]; } else { $fieldName = Text::toCamelName($name); if(array_key_exists($fieldName, $data)) { - $result[$name] = $data[$fieldName]; + $value = $data[$fieldName]; } + else + { + $value = null; + } + } + if(null === $value && !$column->nullable) + { + continue; } + $result[$name] = $value; } return $result; } From 4cb17fd7425ef82989b0dda0c7089e9d89b38bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 09:57:19 +0800 Subject: [PATCH 27/48] =?UTF-8?q?=E5=BA=9F=E9=99=A4=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=B8=ADlastTrace=E9=A1=B9=20=E5=A2=9E=E5=8A=A0=E6=94=AF?= =?UTF-8?q?=E6=8C=81{errorFile}=E3=80=81{errorLine}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Log/Handler/Base.php | 63 ++++++++++--------------------------- src/Log/Handler/Console.php | 14 ++++++++- src/Log/Log.php | 19 ++++++++++- src/Log/Logger.php | 3 +- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/Log/Handler/Base.php b/src/Log/Handler/Base.php index 6b28bb53ba..b33b382583 100644 --- a/src/Log/Handler/Base.php +++ b/src/Log/Handler/Base.php @@ -28,13 +28,7 @@ abstract class Base * 日志格式 * @var string */ - protected $format = '{Y}-{m}-{d} {H}:{i}:{s} [{level}] {message} {lastTrace}'; - - /** - * 最后一个调用跟踪格式 - * @var string - */ - protected $lastTraceFormat = '{file}: {line}, {call}'; + protected $format = '{Y}-{m}-{d} {H}:{i}:{s} [{level}] {message} {errorFile}:{errorLine}'; /** * 调用跟踪格式 @@ -169,15 +163,6 @@ public function getDateTime($time = null) */ public function parseMessage(\Imi\Log\Record $record): string { - $find = $replace = []; - foreach ($record->getContext() as $key => $value) - { - if(is_scalar($value)) - { - $find[] = '{' . $key . '}'; - $replace[] = $value; - } - } return str_replace($find, $replace, $record->getMessage()); } @@ -189,20 +174,31 @@ public function parseMessage(\Imi\Log\Record $record): string public function getLogString(\Imi\Log\Record $record) { $vars = [ - 'message' => $this->parseMessage($record), + 'message' => $record->getMessage(), 'level' => $record->getLevel(), 'timestamp' => $record->getLogTime(), 'trace' => $this->parseTrace($record), - 'lastTrace' => $this->parseLastTrace($record), ]; - $logContent = $this->format; - foreach($vars as $name => $value) + + $find = $replace = []; + foreach($vars as $key => $value) { if(is_scalar($value)) { - $logContent = str_replace('{' . $name . '}', (string)$value, $logContent); + $find[] = '{' . $key . '}'; + $replace[] = $value; } } + foreach ($record->getContext() as $key => $value) + { + if(is_scalar($value)) + { + $find[] = '{' . $key . '}'; + $replace[] = $value; + } + } + $logContent = str_replace($find, $replace, $this->format); + return $this->replaceDateTime($logContent, $record->getLogTime()); } @@ -231,31 +227,6 @@ public function parseTrace(\Imi\Log\Record $record) return implode(PHP_EOL, $result); } - /** - * 处理最后的代码调用跟踪 - * @param \Imi\Log\Record $record - * @return string - */ - public function parseLastTrace(\Imi\Log\Record $record) - { - $trace = $record->getTrace(); - if(!isset($trace[0])) - { - return ''; - } - $vars = $trace[0]; - $vars['call'] = $this->getTraceCall($vars); - $result = $this->lastTraceFormat; - foreach($vars as $name => $value) - { - if(is_scalar($value)) - { - $result = str_replace('{' . $name . '}', (string)$value, $result); - } - } - return $result; - } - /** * 获取调用跟踪的调用 * @return string diff --git a/src/Log/Handler/Console.php b/src/Log/Handler/Console.php index ba49ee3ed5..092f3a4b8c 100644 --- a/src/Log/Handler/Console.php +++ b/src/Log/Handler/Console.php @@ -8,6 +8,13 @@ */ class Console extends Base { + /** + * 要限制输出的字符数量,为null则不限制 + * + * @var int + */ + protected $length; + /** * 真正的保存操作实现 * @return void @@ -16,7 +23,12 @@ protected function __save() { foreach($this->records as $record) { - echo $this->getLogString($record), PHP_EOL; + $content = $this->getLogString($record); + if($this->length > 0) + { + $content = mb_substr($content, 0, $this->length) . '...'; + } + echo $content, PHP_EOL; } } } \ No newline at end of file diff --git a/src/Log/Log.php b/src/Log/Log.php index 8917cabd7d..3003e5ad77 100644 --- a/src/Log/Log.php +++ b/src/Log/Log.php @@ -145,7 +145,18 @@ public static function debug($message, array $context = array()) public static function getTrace() { $backtrace = debug_backtrace(); - return array_splice($backtrace, 2); + return array_splice($backtrace, 3); + } + + /** + * 获取错误文件位置 + * + * @return array + */ + public static function getErrorFile() + { + $backtrace = debug_backtrace(0, 3); + return [$backtrace[2]['file'] ?? '', $backtrace[2]['line'] ?? 0]; } /** @@ -160,6 +171,12 @@ private static function parseContext($context) { $context['trace'] = static::getTrace(); } + if(!isset($context['errorFile'])) + { + list($file, $line) = static::getErrorFile(); + $context['errorFile'] = $file; + $context['errorLine'] = $line; + } return $context; } } \ No newline at end of file diff --git a/src/Log/Logger.php b/src/Log/Logger.php index 8067d57229..5d03853715 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -42,7 +42,8 @@ class Logger extends AbstractLogger LogLevel::EMERGENCY, LogLevel::ERROR, ], - 'format' => '{Y}-{m}-{d} {H}:{i}:{s} [{level}] {message} {lastTrace}' . PHP_EOL . 'Stack trace:' . PHP_EOL . '{trace}', + 'format' => '{Y}-{m}-{d} {H}:{i}:{s} [{level}] {message} {errorFile}:{errorLine}' . PHP_EOL . 'Stack trace:' . PHP_EOL . '{trace}', + 'length' => 1024, ], ] ]; From 9c9e10308f0d3961b193ed1766821fcd30dfa49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 10:47:08 +0800 Subject: [PATCH 28/48] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E4=B8=AD=E5=AF=B9?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93bit=E7=B1=BB=E5=9E=8B=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=A4=84=E7=90=86=E4=B8=BAbool=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/BaseModel.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Model/BaseModel.php b/src/Model/BaseModel.php index 644e4cce6f..3c21f29744 100644 --- a/src/Model/BaseModel.php +++ b/src/Model/BaseModel.php @@ -98,6 +98,20 @@ public function offsetGet($offset) public function offsetSet($offset, $value) { + // 数据库bit类型字段处理 + $column = ModelManager::getPropertyAnnotation($this, $offset, 'Column'); + if(null === $column) + { + $column = ModelManager::getPropertyAnnotation($this, $this->__getCamelName($offset), 'Column'); + } + if(null !== $column) + { + if('bit' === $column->type) + { + $value = (1 == $value || chr(1) == $value); + } + } + $methodName = 'set' . ucfirst($this->__getCamelName($offset)); if(!method_exists($this, $methodName)) { From e297922561ce85aa055f0ddbde0f84a6475b92ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 10:49:58 +0800 Subject: [PATCH 29/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E8=BF=BD=E8=B8=AA=E5=87=86=E7=A1=AE=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Log/ErrorLog.php | 31 ++++++++++++++--------------- src/Log/Logger.php | 47 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/Log/ErrorLog.php b/src/Log/ErrorLog.php index b9b68e7b0b..e1547398ed 100644 --- a/src/Log/ErrorLog.php +++ b/src/Log/ErrorLog.php @@ -55,32 +55,29 @@ public function onError($errno, $errstr, $errfile, $errline) case E_COMPILE_ERROR: case E_USER_ERROR: case E_RECOVERABLE_ERROR: - Log::error($errstr, [ - 'trace' => $this->getTrace(), - ]); + $method = 'error'; break; case E_WARNING: case E_CORE_WARNING: case E_COMPILE_WARNING: case E_USER_WARNING: - Log::warning($errstr, [ - 'trace' => $this->getTrace(), - ]); + $method = 'warning'; break; case E_NOTICE: case E_USER_NOTICE: - Log::notice($errstr, [ - 'trace' => $this->getTrace(), - ]); + $method = 'notice'; break; case E_STRICT: case E_DEPRECATED: case E_USER_DEPRECATED: - Log::info($errstr, [ - 'trace' => $this->getTrace(), - ]); + $method = 'info'; break; } + Log::$method($errstr, [ + 'trace' => $this->getTrace(), + 'errorFile' => $errfile, + 'errorLine' => $errline, + ]); } /** @@ -119,7 +116,9 @@ public function onException(\Throwable $ex) { // 日志处理 Log::error($ex->getMessage(), [ - 'trace' => $ex->getTrace(), + 'trace' => $ex->getTrace(), + 'errorFile' => $ex->getFile(), + 'errorLine' => $ex->getLine(), ]); App::getBean('Logger')->endRequest(); // 请求上下文处理 @@ -139,7 +138,7 @@ protected function getTrace() { $backtrace = debug_backtrace(); $index = null; - $hasNull = false; + $hasNull = false; foreach($backtrace as $i => $item) { if(isset($item['file'])) @@ -148,7 +147,7 @@ protected function getTrace() { if($this->beanCacheFilePath === $item['file']) { - $index = $i + 1; + $index = $i + 2; break; } } @@ -157,7 +156,7 @@ protected function getTrace() { $hasNull = true; } - } + } if(null === $index) { return []; diff --git a/src/Log/Logger.php b/src/Log/Logger.php index 5d03853715..b954b0305f 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -166,9 +166,8 @@ public function save() * 获取代码调用跟踪 * @return array */ - protected function getTrace() + protected function getTrace($backtrace) { - $backtrace = debug_backtrace(); $index = null; $hasNull = false; $beanCacheFilePath = sprintf($this->beanCacheFilePath, Worker::getWorkerID() ?? 'imi'); @@ -178,9 +177,9 @@ protected function getTrace() { if($hasNull) { - if($beanCacheFilePath === $item['file']) + if($beanCacheFilePath === $item['file'] && isset($backtrace[$i + 1]['file']) && 'AbstractLogger.php' !== basename($backtrace[$i + 1]['file'])) { - $index = $i + 1; + $index = $i + 2; break; } } @@ -197,6 +196,37 @@ protected function getTrace() return array_splice($backtrace, $index); } + /** + * 获取错误文件位置 + * + * @return array + */ + public function getErrorFile($backtrace) + { + $index = null; + $hasNull = false; + $beanCacheFilePath = sprintf($this->beanCacheFilePath, Worker::getWorkerID() ?? 'imi'); + foreach($backtrace as $i => $item) + { + if(isset($item['file'])) + { + if($hasNull) + { + if($beanCacheFilePath === $item['file'] && isset($backtrace[$i + 1]['file']) && 'AbstractLogger.php' !== basename($backtrace[$i + 1]['file'])) + { + $index = $i + 1; + break; + } + } + } + else + { + $hasNull = true; + } + } + return [$backtrace[$index]['file'] ?? '', $backtrace[$index]['line'] ?? 0]; + } + /** * 处理context * @@ -205,9 +235,16 @@ protected function getTrace() */ private function parseContext($context) { + $debugBackTrace = debug_backtrace(); if(!isset($context['trace'])) { - $context['trace'] = $this->getTrace(); + $context['trace'] = $this->getTrace($debugBackTrace); + } + if(!isset($context['errorFile'])) + { + list($file, $line) = $this->getErrorFile($debugBackTrace); + $context['errorFile'] = $file; + $context['errorLine'] = $line; } return $context; } From 825dbb5a34c945bf1165edb0194272bfb0a33026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 11:34:45 +0800 Subject: [PATCH 30/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Bean/BeanFactory.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Bean/BeanFactory.php b/src/Bean/BeanFactory.php index 1bf2178e4c..57dbd541ee 100644 --- a/src/Bean/BeanFactory.php +++ b/src/Bean/BeanFactory.php @@ -30,8 +30,15 @@ public static function newInstance($class, ...$args) { File::createDir($path); } - // 暂时改为file_put_contents,用Coroutine::writeFile会导致奇怪的问题,截止目前Swoole:4.0.4 - file_put_contents($cacheFileName, ' '4.0.4') + { + File::writeFile($cacheFileName, ' Date: Tue, 21 Aug 2018 14:32:51 +0800 Subject: [PATCH 31/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8DConnectContext=20Redis?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E8=AF=BB=E5=8F=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/ConnectContext/StoreHandler/Redis.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Server/ConnectContext/StoreHandler/Redis.php b/src/Server/ConnectContext/StoreHandler/Redis.php index 12ebc21974..24cd7c14a9 100644 --- a/src/Server/ConnectContext/StoreHandler/Redis.php +++ b/src/Server/ConnectContext/StoreHandler/Redis.php @@ -210,7 +210,8 @@ public function read(string $key): array { return $this->useRedis(function($resource, $redis) use($key){ $redisKey = $this->getRedisKey($key); - return $redis->get($redisKey) ?? []; + $result = $redis->get($redisKey); + return $result ? $result : []; }); } From ff250377768b8a9971a240f9950d524b0b2a1b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 14:33:07 +0800 Subject: [PATCH 32/48] =?UTF-8?q?=E9=80=82=E9=85=8D=E6=94=AF=E6=8C=81=20Sw?= =?UTF-8?q?oole=204.1.0=20=E4=B8=80=E9=94=AE=E5=8D=8F=E7=A8=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Listener/WorkerInit.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Listener/WorkerInit.php b/src/Listener/WorkerInit.php index dcee56c3a4..4e01bba991 100644 --- a/src/Listener/WorkerInit.php +++ b/src/Listener/WorkerInit.php @@ -29,6 +29,15 @@ class WorkerInit implements IWorkerStartEventListener */ public function handle(WorkerStartEventParam $e) { + if(!$e->server->getSwooleServer()->taskworker) + { + // swoole 4.1.0 一键协程化 + if(method_exists('\Swoole\Runtime', 'enableCoroutine') && (Helper::getMain(App::getNamespace())->getConfig()['enableCoroutine'] ?? true)) + { + \Swoole\Runtime::enableCoroutine(true); + } + } + $GLOBALS['WORKER_START_END_RESUME_COIDS'] = []; // 当前进程的 WorkerID 设置 From 5b594ad0002b5ead7c60ab2011404ecbc6c157e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 14:58:05 +0800 Subject: [PATCH 33/48] =?UTF-8?q?=E6=96=B0=E5=A2=9EResult->getSql()?= =?UTF-8?q?=E3=80=81Result->getStatement()=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Db/Query/Interfaces/IResult.php | 16 ++++++++++++++++ src/Db/Query/Result.php | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/Db/Query/Interfaces/IResult.php b/src/Db/Query/Interfaces/IResult.php index 31bf99a53d..bec6fb2d7c 100644 --- a/src/Db/Query/Interfaces/IResult.php +++ b/src/Db/Query/Interfaces/IResult.php @@ -1,6 +1,8 @@ statement->fetchAll()); } + + /** + * 获取执行的SQL语句 + * + * @return string + */ + public function getSql() + { + return $this->statement->getSql(); + } + + /** + * 获取结果集对象 + * + * @return \Imi\Db\Interfaces\IStatement + */ + public function getStatement(): IStatement + { + return $this->statement; + } } \ No newline at end of file From 373f00a2c2cd433ff4950c8d8a2bd0c773263148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 15:23:18 +0800 Subject: [PATCH 34/48] =?UTF-8?q?=E6=96=B0=E5=A2=9EManager=E3=80=81Worker?= =?UTF-8?q?=E3=80=81Process=E8=BF=9B=E7=A8=8B=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E6=97=B6=E9=87=8D=E6=96=B0=E6=92=AD=E7=A7=8D=E9=9A=8F=E6=9C=BA?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Listener/OnManagerStart.php | 3 +++ src/Listener/WorkerInit.php | 3 +++ src/Process/ProcessManager.php | 2 ++ src/Process/ProcessPoolManager.php | 2 ++ 4 files changed, 10 insertions(+) diff --git a/src/Listener/OnManagerStart.php b/src/Listener/OnManagerStart.php index 5d1a914e94..e83fe7afef 100644 --- a/src/Listener/OnManagerStart.php +++ b/src/Listener/OnManagerStart.php @@ -27,6 +27,9 @@ class OnManagerStart implements IManagerStartEventListener */ public function handle(ManagerStartEventParam $e) { + // 随机数播种 + mt_srand(); + // 进程PID记录 $fileName = File::path(dirname($_SERVER['SCRIPT_NAME']), str_replace('\\', '-', App::getNamespace()) . '.pid'); File::writeFile($fileName, json_encode([ diff --git a/src/Listener/WorkerInit.php b/src/Listener/WorkerInit.php index 4e01bba991..5280ce7cc6 100644 --- a/src/Listener/WorkerInit.php +++ b/src/Listener/WorkerInit.php @@ -29,6 +29,9 @@ class WorkerInit implements IWorkerStartEventListener */ public function handle(WorkerStartEventParam $e) { + // 随机数播种 + mt_srand(); + if(!$e->server->getSwooleServer()->taskworker) { // swoole 4.1.0 一键协程化 diff --git a/src/Process/ProcessManager.php b/src/Process/ProcessManager.php index 13417a07ef..ec40eea4f0 100644 --- a/src/Process/ProcessManager.php +++ b/src/Process/ProcessManager.php @@ -55,6 +55,8 @@ public static function create($name, $args = [], $redirectStdinStdout = null, $p $process = new \Swoole\Process(function(\Swoole\Process $swooleProcess) use($processInstance, $name, $processOption){ // 设置进程名称 $swooleProcess->name($name); + // 随机数播种 + mt_srand(); if($processOption['Process']->unique) { if(!static::lockProcess($name)) diff --git a/src/Process/ProcessPoolManager.php b/src/Process/ProcessPoolManager.php index fc986bdf14..037bec4092 100644 --- a/src/Process/ProcessPoolManager.php +++ b/src/Process/ProcessPoolManager.php @@ -50,6 +50,8 @@ public static function create($name, $workerNum = null, $args = [], $ipcType = 0 $pool = new \Swoole\Process\Pool($workerNum, $ipcType, $msgQueueKey); $pool->on('WorkerStart', function ($pool, $workerId) use($name, $workerNum, $args, $ipcType, $msgQueueKey, $processPoolOption) { + // 随机数播种 + mt_srand(); $processInstance = BeanFactory::newInstance($processPoolOption['className'], $args); App::initWorker(); // 进程开始事件 From af2ee315854e4bc0f806297c884eb54476ec2aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 17:35:54 +0800 Subject: [PATCH 35/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCoroutineChannelManager?= =?UTF-8?q?::stats()=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Util/CoroutineChannelManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Util/CoroutineChannelManager.php b/src/Util/CoroutineChannelManager.php index 580db217d4..3057ff1ae8 100644 --- a/src/Util/CoroutineChannelManager.php +++ b/src/Util/CoroutineChannelManager.php @@ -87,7 +87,7 @@ public static function pop(string $name, $timeout = 0) */ public static function stats(string $name): array { - return parent::stats($name); + return static::getInstance($name)->stats(); } /** From c8e8b2de523d97b49d300b00d91f8ee73ac39e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Tue, 21 Aug 2018 17:47:52 +0800 Subject: [PATCH 36/48] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=B1=A0=E5=AD=90?= =?UTF-8?q?=E5=85=BC=E5=AE=B9swoole=204.0.3=E5=8F=8A=E4=BB=A5=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pool/BaseAsyncPool.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Pool/BaseAsyncPool.php b/src/Pool/BaseAsyncPool.php index 374d6012f9..4aa45c92c7 100644 --- a/src/Pool/BaseAsyncPool.php +++ b/src/Pool/BaseAsyncPool.php @@ -46,10 +46,17 @@ public function getResource(): IPoolResource } else { - // 等待其他协程使用完成后释放连接 - $read = [$this->queue]; - $write = null; - $selectResult = Channel::select($read, $write, $this->config->getWaitTimeout() / 1000); + if(SWOOLE_VERSION < '4.0.3') + { + // 等待其他协程使用完成后释放连接 + $read = [$this->queue]; + $write = null; + $selectResult = Channel::select($read, $write, $this->config->getWaitTimeout() / 1000); + } + else + { + $selectResult = Channel::pop($this->config->getWaitTimeout() / 1000); + } if(false === $selectResult) { throw new \RuntimeException('AsyncPool getResource timeout'); From bcf2f0b33917859cdaac668fef6e904a85bd372d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 09:55:42 +0800 Subject: [PATCH 37/48] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=B1=A0=E5=AD=90?= =?UTF-8?q?=E5=85=BC=E5=AE=B9swoole=204.0.3=E5=8F=8A=E4=BB=A5=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pool/BaseAsyncPool.php | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/Pool/BaseAsyncPool.php b/src/Pool/BaseAsyncPool.php index 4aa45c92c7..96866b560f 100644 --- a/src/Pool/BaseAsyncPool.php +++ b/src/Pool/BaseAsyncPool.php @@ -55,7 +55,7 @@ public function getResource(): IPoolResource } else { - $selectResult = Channel::pop($this->config->getWaitTimeout() / 1000); + $selectResult = $this->queue->pop($this->config->getWaitTimeout() / 1000); } if(false === $selectResult) { @@ -63,7 +63,18 @@ public function getResource(): IPoolResource } } } - $resource = $this->queue->pop(); + else + { + $selectResult = true; + } + if(true === $selectResult) + { + $resource = $this->queue->pop(); + } + else + { + $resource = $selectResult; + } if(!$resource->checkState()) { $resource->open(); @@ -91,13 +102,27 @@ public function tryGetResource() } $read = [$this->queue]; $write = null; - // Coroutine\Channel::select() 最小超时时间1毫秒 - $result = Channel::select($read, $write, 0.001); + // Coroutine\Channel::select()/->pop() 最小超时时间1毫秒 + if(SWOOLE_VERSION < '4.0.3') + { + $result = Channel::select($read, $write, 0.001); + } + else + { + $result = $this->queue->pop(0.001); + } if(false === $result) { return false; } - $resource = $this->queue->pop(); + if(true === $result) + { + $resource = $this->queue->pop(); + } + else + { + $resource = $result; + } if(!$resource->checkState()) { $resource->open(); From ba00e216509d8a175d1e479d3d577f573fcbcc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 10:02:46 +0800 Subject: [PATCH 38/48] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=B1=A0=E5=AD=90?= =?UTF-8?q?=E5=85=BC=E5=AE=B9swoole=204.0.3=E5=8F=8A=E4=BB=A5=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pool/BaseAsyncPool.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Pool/BaseAsyncPool.php b/src/Pool/BaseAsyncPool.php index 96866b560f..566d4fcb60 100644 --- a/src/Pool/BaseAsyncPool.php +++ b/src/Pool/BaseAsyncPool.php @@ -37,6 +37,7 @@ protected function initQueue() */ public function getResource(): IPoolResource { + $selectResult = true; if($this->getFree() <= 0) { if($this->getCount() < $this->config->getMaxResources()) @@ -63,10 +64,6 @@ public function getResource(): IPoolResource } } } - else - { - $selectResult = true; - } if(true === $selectResult) { $resource = $this->queue->pop(); From c85fb31e916bbadbca545fb77f7b774342e0c6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 11:39:45 +0800 Subject: [PATCH 39/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=E8=A7=86=E5=9B=BE=EF=BC=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=AD=97=E6=AE=B5=E4=B8=BA=E4=B8=BB?= =?UTF-8?q?=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tool/Tools/Generate/Model/ModelGenerate.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Tool/Tools/Generate/Model/ModelGenerate.php b/src/Tool/Tools/Generate/Model/ModelGenerate.php index 4e9a8285c3..e338688efe 100644 --- a/src/Tool/Tools/Generate/Model/ModelGenerate.php +++ b/src/Tool/Tools/Generate/Model/ModelGenerate.php @@ -76,7 +76,7 @@ public function generate($namespace, $database, $poolName, $prefix, $include, $e 'fields' => [], ]; $fields = $query->bindValue(':table', $table)->execute('show full columns from ' . $table)->getArray(); - $this->parseFields($fields, $data); + $this->parseFields($fields, $data, 'VIEW' === $table['TABLE_TYPE']); $content = $this->renderTemplate($data); File::writeFile($fileName, $content); } @@ -120,15 +120,23 @@ private function getClassName($table, $prefix) * 处理字段信息 * @param array $fields * @param array $data + * @param boolean $isView * @return void */ - private function parseFields($fields, &$data) + private function parseFields($fields, &$data, $isView) { $idCount = 0; - foreach($fields as $field) + foreach($fields as $i => $field) { $this->parseFieldType($field['Type'], $typeName, $length, $accuracy); - $isPk = 'PRI' === $field['Key']; + if($isView && 0 === $i) + { + $isPk = true; + } + else + { + $isPk = 'PRI' === $field['Key']; + } $data['fields'][] = [ 'name' => $field['Field'], 'varName' => Text::toCamelName($field['Field']), From 87c85b44c79e378babd212d74b67aa483c6de42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 11:43:22 +0800 Subject: [PATCH 40/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=E8=A7=86=E5=9B=BE=EF=BC=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=AD=97=E6=AE=B5=E4=B8=BA=E4=B8=BB?= =?UTF-8?q?=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tool/Tools/Generate/Model/ModelGenerate.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Tool/Tools/Generate/Model/ModelGenerate.php b/src/Tool/Tools/Generate/Model/ModelGenerate.php index e338688efe..19fcbb6893 100644 --- a/src/Tool/Tools/Generate/Model/ModelGenerate.php +++ b/src/Tool/Tools/Generate/Model/ModelGenerate.php @@ -40,19 +40,20 @@ public function generate($namespace, $database, $poolName, $prefix, $include, $e $database = $query->execute('select database()')->getScalar(); } // 表 - $tables = $query->tableRaw('information_schema.TABLES') + $list = $query->tableRaw('information_schema.TABLES') ->where('TABLE_SCHEMA', '=', $database) ->whereIn('TABLE_TYPE', [ 'BASE TABLE', 'VIEW', ]) - ->field('TABLE_NAME') + ->field('TABLE_NAME,TABLE_TYPE') ->select() - ->getColumn(); + ->getArray(); // model保存路径 $modelPath = Imi::getNamespacePath($namespace); - foreach($tables as $table) + foreach($list as $item) { + $table = $item['TABLE_NAME']; if(!$this->checkTable($table, $include, $exclude)) { // 不符合$include和$exclude @@ -76,7 +77,7 @@ public function generate($namespace, $database, $poolName, $prefix, $include, $e 'fields' => [], ]; $fields = $query->bindValue(':table', $table)->execute('show full columns from ' . $table)->getArray(); - $this->parseFields($fields, $data, 'VIEW' === $table['TABLE_TYPE']); + $this->parseFields($fields, $data, 'VIEW' === $item['TABLE_TYPE']); $content = $this->renderTemplate($data); File::writeFile($fileName, $content); } From c195b4bba1463dbe5569a627118977b4525bdae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 11:44:12 +0800 Subject: [PATCH 41/48] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=E8=A7=86=E5=9B=BE=EF=BC=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=AD=97=E6=AE=B5=E4=B8=BA=E4=B8=BB?= =?UTF-8?q?=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tool/Tools/Generate/Model/ModelGenerate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tool/Tools/Generate/Model/ModelGenerate.php b/src/Tool/Tools/Generate/Model/ModelGenerate.php index 19fcbb6893..e7854dc318 100644 --- a/src/Tool/Tools/Generate/Model/ModelGenerate.php +++ b/src/Tool/Tools/Generate/Model/ModelGenerate.php @@ -46,7 +46,7 @@ public function generate($namespace, $database, $poolName, $prefix, $include, $e 'BASE TABLE', 'VIEW', ]) - ->field('TABLE_NAME,TABLE_TYPE') + ->field('TABLE_NAME', 'TABLE_TYPE') ->select() ->getArray(); // model保存路径 From 844e5cd020794fea5277aa1030f4d1415923d977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 17:16:41 +0800 Subject: [PATCH 42/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8DManagerStop=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/Base.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Server/Base.php b/src/Server/Base.php index b48d1ea35e..5de6e80684 100644 --- a/src/Server/Base.php +++ b/src/Server/Base.php @@ -13,6 +13,7 @@ use Imi\Server\Event\Param\ShutdownEventParam; use Imi\Server\Event\Param\WorkerStopEventParam; use Doctrine\Common\Annotations\AnnotationReader; +use Imi\Server\Event\Param\ManagerStopEventParam; use Imi\Server\Event\Param\PipeMessageEventParam; use Imi\Server\Event\Param\WorkerErrorEventParam; use Imi\Server\Event\Param\WorkerStartEventParam; From c547fa0dfb1811a9866f2b2b3f77ad809237c2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 17:21:20 +0800 Subject: [PATCH 43/48] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E4=BF=9D=E5=AD=98=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E6=97=A5=E5=BF=97=E4=BC=9A=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E4=BC=A0=E5=85=A5=E5=A4=84=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Listener/OnManagerStop.php | 24 ++++++++++ src/Listener/OnWorkerStop.php | 24 ++++++++++ src/Log/ErrorLog.php | 2 - src/Log/Logger.php | 46 +++++-------------- src/Server/Http/Listener/AfterRequest.php | 2 - .../TcpServer/Listener/AfterReceive.php | 2 - .../WebSocket/Listener/AfterMessage.php | 2 - 7 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 src/Listener/OnManagerStop.php create mode 100644 src/Listener/OnWorkerStop.php diff --git a/src/Listener/OnManagerStop.php b/src/Listener/OnManagerStop.php new file mode 100644 index 0000000000..f158ae2f45 --- /dev/null +++ b/src/Listener/OnManagerStop.php @@ -0,0 +1,24 @@ +save(); + } +} \ No newline at end of file diff --git a/src/Listener/OnWorkerStop.php b/src/Listener/OnWorkerStop.php new file mode 100644 index 0000000000..0d8f42f45e --- /dev/null +++ b/src/Listener/OnWorkerStop.php @@ -0,0 +1,24 @@ +save(); + } +} \ No newline at end of file diff --git a/src/Log/ErrorLog.php b/src/Log/ErrorLog.php index e1547398ed..0804580f63 100644 --- a/src/Log/ErrorLog.php +++ b/src/Log/ErrorLog.php @@ -102,7 +102,6 @@ public function onShutdown() ]); } $logger = App::getBean('Logger'); - $logger->endRequest(); $logger->save(); exit; } @@ -120,7 +119,6 @@ public function onException(\Throwable $ex) 'errorFile' => $ex->getFile(), 'errorLine' => $ex->getLine(), ]); - App::getBean('Logger')->endRequest(); // 请求上下文处理 if(RequestContext::exsits()) { diff --git a/src/Log/Logger.php b/src/Log/Logger.php index b954b0305f..d88a826f5f 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -26,8 +26,16 @@ class Logger extends AbstractLogger 'class' => \Imi\Log\Handler\Console::class, 'options' => [ 'levels' => [ - LogLevel::DEBUG, LogLevel::INFO, + ], + 'format' => '{Y}-{m}-{d} {H}:{i}:{s} [{level}] {message}', + ], + ], + [ + 'class' => \Imi\Log\Handler\Console::class, + 'options' => [ + 'levels' => [ + LogLevel::DEBUG, LogLevel::NOTICE, LogLevel::WARNING, ], @@ -74,13 +82,6 @@ class Logger extends AbstractLogger */ private $beanCacheFilePath; - /** - * 自动保存间隔,单位:秒 - * - * @var integer - */ - protected $autoSaveInterval = 10; - /** * 定时器ID * @@ -95,13 +96,6 @@ public function __init() $this->handlers[] = BeanFactory::newInstance($handlerOption['class'], $handlerOption['options']); } $this->beanCacheFilePath = Imi::getBeanClassCachePath('%s', str_replace('\\', DIRECTORY_SEPARATOR, __CLASS__) . '.php'); - if($this->autoSaveInterval > 0) - { - $this->timerID = swoole_timer_tick($this->autoSaveInterval * 1000, function(){ - $this->endRequest(); - $this->save(); - }); - } } public function __destruct() @@ -127,26 +121,10 @@ public function log($level, $message, array $context = array()) $context = $this->parseContext($context); $trace = $context['trace']; $logTime = time(); - $this->records[] = new Record($level, $message, $context, $trace, $logTime); - if(!Coroutine::isIn()) - { - $this->endRequest(); - } - } - - /** - * 当请求结束时调用 - * @return void - */ - public function endRequest() - { - if(isset($this->records[0])) + $record = new Record($level, $message, $context, $trace, $logTime); + foreach($this->handlers as $handler) { - foreach($this->handlers as $handler) - { - $handler->logBatch($this->records); - } - $this->records = []; + $handler->log($record); } } diff --git a/src/Server/Http/Listener/AfterRequest.php b/src/Server/Http/Listener/AfterRequest.php index 1c68ff68e1..f0b758535c 100644 --- a/src/Server/Http/Listener/AfterRequest.php +++ b/src/Server/Http/Listener/AfterRequest.php @@ -22,8 +22,6 @@ class AfterRequest implements IRequestEventListener */ public function handle(RequestEventParam $e) { - // 日志处理 - App::getBean('Logger')->endRequest(); // 释放请求的进程池资源 PoolManager::destroyCurrentContext(); // 销毁请求上下文 diff --git a/src/Server/TcpServer/Listener/AfterReceive.php b/src/Server/TcpServer/Listener/AfterReceive.php index c77debac26..b672702e63 100644 --- a/src/Server/TcpServer/Listener/AfterReceive.php +++ b/src/Server/TcpServer/Listener/AfterReceive.php @@ -22,8 +22,6 @@ class AfterReceive implements IReceiveEventListener */ public function handle(ReceiveEventParam $e) { - // 日志处理 - App::getBean('Logger')->endRequest(); // 释放请求的进程池资源 PoolManager::destroyCurrentContext(); // 销毁请求上下文 diff --git a/src/Server/WebSocket/Listener/AfterMessage.php b/src/Server/WebSocket/Listener/AfterMessage.php index b3a897d072..9549065516 100644 --- a/src/Server/WebSocket/Listener/AfterMessage.php +++ b/src/Server/WebSocket/Listener/AfterMessage.php @@ -22,8 +22,6 @@ class AfterMessage implements IMessageEventListener */ public function handle(MessageEventParam $e) { - // 日志处理 - App::getBean('Logger')->endRequest(); // 释放请求的进程池资源 PoolManager::destroyCurrentContext(); // 销毁请求上下文 From 112efe2261adace9a08aacfd5ef439f91598926e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 17:22:02 +0800 Subject: [PATCH 44/48] =?UTF-8?q?=E6=96=B0=E5=A2=9EProcessManager::runWith?= =?UTF-8?q?Manager=E6=96=B9=E6=B3=95=EF=BC=8C=E5=8F=AF=E4=BB=A5=E5=9C=A8IM?= =?UTF-8?q?I.SERVERS.CREATE.AFTER=E4=BA=8B=E4=BB=B6=E4=B8=AD=E4=BD=BF?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Process/ProcessManager.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Process/ProcessManager.php b/src/Process/ProcessManager.php index ec40eea4f0..b4a373871b 100644 --- a/src/Process/ProcessManager.php +++ b/src/Process/ProcessManager.php @@ -8,6 +8,7 @@ use Imi\Process\Parser\ProcessParser; use Imi\Process\Exception\ProcessAlreadyRunException; use Imi\Util\Imi; +use Imi\ServerManage; /** * 进程管理类 @@ -176,6 +177,22 @@ public static function coRun($name, $args = [], $redirectStdinStdout = null, $pi }); } + /** + * 挂靠Manager进程运行进程 + * + * @param string $name + * @param array $args + * @param boolean $redirectStdinStdout + * @param int $pipeType + * @return void + */ + public static function runWithManager($name, $args = [], $redirectStdinStdout = null, $pipeType = null) + { + $process = static::create($name, $args, $redirectStdinStdout, $pipeType); + $server = ServerManage::getServer('main')->getSwooleServer(); + $server->addProcess($process); + } + /** * 锁定进程,实现unique * From 0b69d92e3aeb30184dee9baee5532d16f761b9e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Wed, 22 Aug 2018 17:22:39 +0800 Subject: [PATCH 45/48] =?UTF-8?q?=E7=83=AD=E6=9B=B4=E6=96=B0=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E7=8E=B0=E5=9C=A8=E7=BB=91=E5=AE=9A=E5=88=B0Manager?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Listener/OnManagerStart.php | 4 ---- src/Listener/OnServerCreateAfter.php | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/Listener/OnServerCreateAfter.php diff --git a/src/Listener/OnManagerStart.php b/src/Listener/OnManagerStart.php index e83fe7afef..ea34f47c72 100644 --- a/src/Listener/OnManagerStart.php +++ b/src/Listener/OnManagerStart.php @@ -36,9 +36,5 @@ public function handle(ManagerStartEventParam $e) 'masterPID' => Swoole::getMasterPID(), 'managerPID' => Swoole::getManagerPID(), ])); - - // 热更新 - $process = ProcessManager::create('hotUpdate'); - $process->start(); } } \ No newline at end of file diff --git a/src/Listener/OnServerCreateAfter.php b/src/Listener/OnServerCreateAfter.php new file mode 100644 index 0000000000..c60a52a7bf --- /dev/null +++ b/src/Listener/OnServerCreateAfter.php @@ -0,0 +1,24 @@ + Date: Wed, 22 Aug 2018 17:23:14 +0800 Subject: [PATCH 46/48] =?UTF-8?q?=E4=BC=98=E5=8C=96ConnectContext=E5=92=8C?= =?UTF-8?q?Group=E7=9A=84Redis=E5=88=9D=E5=A7=8B=E5=8C=96=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConnectContext/StoreHandler/Redis.php | 54 ++++++++++++------- src/Server/Group/Handler/Redis.php | 54 ++++++++++++------- 2 files changed, 68 insertions(+), 40 deletions(-) diff --git a/src/Server/ConnectContext/StoreHandler/Redis.php b/src/Server/ConnectContext/StoreHandler/Redis.php index 24cd7c14a9..e225f4a140 100644 --- a/src/Server/ConnectContext/StoreHandler/Redis.php +++ b/src/Server/ConnectContext/StoreHandler/Redis.php @@ -1,7 +1,10 @@ useRedis(function($resource, $redis){ - // 判断master进程pid - $this->masterPID = Swoole::getMasterPID(); - $hasPing = $this->hasPing($redis); - $storeMasterPID = $redis->get($this->key); - if(null === $storeMasterPID) - { - // 没有存储master进程pid - $this->initRedis($redis, $storeMasterPID); - } - else if($this->masterPID != $storeMasterPID) - { - if($hasPing) + if(0 === Worker::getWorkerID()) + { + $this->useRedis(function($resource, $redis){ + // 判断master进程pid + $this->masterPID = Swoole::getMasterPID(); + $storeMasterPID = $redis->get($this->key); + if(null === $storeMasterPID) { - // 与master进程ID不等 - throw new \RuntimeException('ConnectContextRedis repeat'); + // 没有存储master进程pid + $this->initRedis($redis, $storeMasterPID); } - else + else if($this->masterPID != $storeMasterPID) { - $this->initRedis($redis, $storeMasterPID); + $hasPing = $this->hasPing($redis); + if($hasPing) + { + Log::warning('ConnectContextRedis key has been used, waiting...'); + sleep($this->heartbeatTtl); + $hasPing = $this->hasPing($redis); + } + if($hasPing) + { + // 与master进程ID不等 + Log::emergency('ConnectContextRedis key has been used'); + ServerManage::getServer('main')->getSwooleServer()->shutdown(); + } + else + { + $this->initRedis($redis, $storeMasterPID); + Log::info('ConnectContextRedis key init'); + } } - } - $this->startPing($redis); - }); + $this->startPing($redis); + }); + } } /** diff --git a/src/Server/Group/Handler/Redis.php b/src/Server/Group/Handler/Redis.php index 7ab456ddcd..b37109c05f 100644 --- a/src/Server/Group/Handler/Redis.php +++ b/src/Server/Group/Handler/Redis.php @@ -7,6 +7,9 @@ use Imi\Pool\PoolManager; use Imi\Bean\Annotation\Bean; use Swoole\Coroutine\Redis as CoRedis; +use Imi\Worker; +use Imi\Log\Log; +use Imi\ServerManage; /** * @Bean("GroupRedis") @@ -74,30 +77,41 @@ public function __init() { return; } - $this->useRedis(function($resource, $redis){ - // 判断master进程pid - $this->masterPID = Swoole::getMasterPID(); - $hasPing = $this->hasPing($redis); - $storeMasterPID = $redis->get($this->key); - if(null === $storeMasterPID) - { - // 没有存储master进程pid - $this->initRedis($redis, $storeMasterPID); - } - else if($this->masterPID != $storeMasterPID) - { - if($hasPing) + if(0 === Worker::getWorkerID()) + { + $this->useRedis(function($resource, $redis){ + // 判断master进程pid + $this->masterPID = Swoole::getMasterPID(); + $storeMasterPID = $redis->get($this->key); + if(null === $storeMasterPID) { - // 与master进程ID不等 - throw new \RuntimeException('Server Group Redis repeat'); + // 没有存储master进程pid + $this->initRedis($redis, $storeMasterPID); } - else + else if($this->masterPID != $storeMasterPID) { - $this->initRedis($redis, $storeMasterPID); + $hasPing = $this->hasPing($redis); + if($hasPing) + { + Log::warning('Redis server group key has been used, waiting...'); + sleep($this->heartbeatTtl); + $hasPing = $this->hasPing($redis); + } + if($hasPing) + { + // 与master进程ID不等 + Log::emergency('Redis server group key has been used'); + ServerManage::getServer('main')->getSwooleServer()->shutdown(); + } + else + { + $this->initRedis($redis, $storeMasterPID); + Log::info('Redis server group key init'); + } } - } - $this->startPing($redis); - }); + $this->startPing($redis); + }); + } } /** From 5577734e0d8c392521290d502f76df2848906ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Thu, 23 Aug 2018 16:36:49 +0800 Subject: [PATCH 47/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E8=BF=9E=E6=8E=A5=E9=85=8D=E7=BD=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E7=94=A8username=E6=8C=87=E5=AE=9A=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Db/Drivers/CoroutineMysql/Driver.php | 10 +++++++--- src/Db/Drivers/PdoMysql/Driver.php | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Db/Drivers/CoroutineMysql/Driver.php b/src/Db/Drivers/CoroutineMysql/Driver.php index 2142388ca5..18554cd562 100644 --- a/src/Db/Drivers/CoroutineMysql/Driver.php +++ b/src/Db/Drivers/CoroutineMysql/Driver.php @@ -44,7 +44,7 @@ class Driver implements IDb * 参数格式: * [ * 'host' => 'MySQL IP地址', - * 'user' => '数据用户', + * 'username' => '数据用户', * 'password' => '数据库密码', * 'database' => '数据库名', * 'port' => 'MySQL端口 默认3306 可选参数', @@ -57,9 +57,13 @@ class Driver implements IDb public function __construct($option = []) { $this->option = $option; - if(!isset($this->option['username'])) + if(isset($this->option['username'])) { - $this->option['username'] = 'root'; + $this->option['user'] = $this->option['username']; + } + else + { + $this->option['user'] = 'root'; } if(!isset($option['password'])) { diff --git a/src/Db/Drivers/PdoMysql/Driver.php b/src/Db/Drivers/PdoMysql/Driver.php index eb1159b6e6..251270286a 100644 --- a/src/Db/Drivers/PdoMysql/Driver.php +++ b/src/Db/Drivers/PdoMysql/Driver.php @@ -42,7 +42,7 @@ class Driver implements IDb * 参数格式: * [ * 'host' => 'MySQL IP地址', - * 'user' => '数据用户', + * 'username' => '数据用户', * 'password' => '数据库密码', * 'database' => '数据库名', * 'port' => 'MySQL端口 默认3306 可选参数', From 73b87a16444b8627ef19515ac15c4814c14351a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E6=B6=A6?= Date: Thu, 23 Aug 2018 17:03:50 +0800 Subject: [PATCH 48/48] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=97=B6=EF=BC=8C=E5=A6=82=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E4=B8=8D=E5=AD=98=E5=9C=A8=E5=88=99=E8=87=AA=E5=8A=A8=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Tool/Tools/Generate/Model/ModelGenerate.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tool/Tools/Generate/Model/ModelGenerate.php b/src/Tool/Tools/Generate/Model/ModelGenerate.php index e7854dc318..dc4f36469a 100644 --- a/src/Tool/Tools/Generate/Model/ModelGenerate.php +++ b/src/Tool/Tools/Generate/Model/ModelGenerate.php @@ -51,6 +51,7 @@ public function generate($namespace, $database, $poolName, $prefix, $include, $e ->getArray(); // model保存路径 $modelPath = Imi::getNamespacePath($namespace); + File::createDir($modelPath); foreach($list as $item) { $table = $item['TABLE_NAME'];