php-msf icon indicating copy to clipboard operation
php-msf copied to clipboard

Mi.php context = null

Open wuchuguang opened this issue 8 years ago • 2 comments

/**
     * 通过对象池生成对象
     *
     * @param array $args
     * @return \stdClass|mixed
     */
    public function getObject(...$args)
    {
       //请求间隔久时,这里会出现this->context = null的情况。Miner过来的getObject(Mysql::class,...)
        return $this->context->getObjectPool()->get(...$args);
    }

wuchuguang avatar Oct 17 '17 07:10 wuchuguang

这个问题还能复现吗?

xudianyang avatar Oct 23 '17 15:10 xudianyang

这个问题不但能复现, 而且是百分百复现, 请求间隔久没试过, 但是频繁访问下绝对会出现, 假设有控制器A和控制器B, 两个控制器Index方法都有数据库连接操作, 连续请求控制器A多次, 然后立刻请求控制器B多次, 交替一次或者多次之后就会出现call member method getObjectPool on null, 经过大量调试排查问题应该是出在控制器销毁对象那里, 分析原因可能是因为之前的请求尚未处理完成, 从查看monitor可以看到worker下coroutine数量不为0, 但是实际上这些coroutine在某个时间点已经执行完毕, 没有回收, 或者回收不完全, 总之这些coroutine一直存在, 新的请求进来之后被错乱的对象销毁机制销毁掉了context属性, 最终导致Miner的go方法调用失败报错, 目前的解决方案是移除controller控制器destroy方法中销毁对象的几行代码, 然后在Scheduler类的检测coroutine超时的方法中检测task->getRoutine是否为null, 如果为null, 强行调用task的destroy方法, 目前观察内存没有暴涨, 也没有再出现过context突然变成null的问题.

qxhy123 avatar Apr 24 '18 10:04 qxhy123