Closed it-gan closed 2 years ago
easyswoole: 3.4.6 orm:1.5.2
前提条件:数据库连接wait_timeout设置了90秒,一个自定义进程读取redis数据。
封装了一个数据库基类(继承AbstractModel),然后一个普通model继承它($tableName没有指定),是通过重写基类schemaInfo读取表名的。会出现gone way? 但是如果把model中的$tableName指定了就不再出现。这是什么操作?
是否第一次获取表的schema信息,将连接defer了,后面不可以使用了?
CoreModel.php
<?php namespace App\Model\Bad; use EasySwoole\ORM\AbstractModel; use EasySwoole\EasySwoole\Config; use EasySwoole\ORM\Utility\Schema\Table; use Illuminate\Support\Str; class CoreModel extends AbstractModel { public function schemaInfo(bool $isCache = true): Table { // 根据模型名称生成表名称 $prefix = Config::getInstance()->getConf('DB')['prefix']; $name = preg_replace('/\\\\/', '/', get_class($this)); $this->tableName = Str::snake(basename($name)); if (!Str::startsWith($this->tableName, $prefix) && $prefix) { $this->tableName = $prefix . $this->tableName; } return parent::schemaInfo($isCache); } }
Canteen.php
<?php namespace App\Model\Bad; class Canteen extends CoreModel { // protected $tableName = "rx_canteen"; }
DBProcess.php
<?php namespace App\Process; use App\Model\Bad\Canteen; use EasySwoole\Component\Process\AbstractProcess; use EasySwoole\EasySwoole\Logger; use EasySwoole\Redis\Redis as ESRedis; use EasySwoole\RedisPool\RedisPool; use Swoole\Coroutine; class DBProcess extends AbstractProcess { protected function run($arg) { while (1) { try { $data = self::rPop("db:test"); if (empty($data)) { Coroutine::sleep(3); continue; } else { $rt = self::generalModel($data); Logger::getInstance()->log("DBProcess 执行成功--->" . json_encode($rt) . PHP_EOL); Coroutine::sleep(1); } } catch (\Throwable $e) { Logger::getInstance()->log("DBProcess Throwable--->" . $e->getMessage() . $e->getTraceAsString() . $e->getFile() . $e->getLine() . PHP_EOL); } } } private static function generalModel($id = 5) { return Canteen::create()->where(["id" => $id])->field("id,name")->get(); } public static function rPop($key, $num = 1) { return RedisPool::invoke(function (ESRedis $redis) use ($key, $num) { if ($num == 1) { return $redis->rPop($key); } else { $redis->startPipe(); $redis->lRange($key, 0, $num - 1); $redis->lTrim($key, $num, -1); return $redis->execPipe(); } }); } }
easyswoole框架版本号、orm组件版本号 [Version]
easyswoole: 3.4.6 orm:1.5.2
问题描述和截图 [Question]
前提条件:数据库连接wait_timeout设置了90秒,一个自定义进程读取redis数据。
封装了一个数据库基类(继承AbstractModel),然后一个普通model继承它($tableName没有指定),是通过重写基类schemaInfo读取表名的。会出现gone way? 但是如果把model中的$tableName指定了就不再出现。这是什么操作?
排查情况和最小复现脚本 [Tests and Recurrence]
是否第一次获取表的schema信息,将连接defer了,后面不可以使用了?
CoreModel.php
Canteen.php
DBProcess.php