think-swoole
think-swoole copied to clipboard
增加3.0子协程功能
修复和功能描述: 1.合并4.0的沙盒获取方式 2.创建子协程造成获取Container失败 3.子协程逃逸后沙盒内存泄漏的处理 问题描述:
- 3.0不支持在如控制器等地方直接go(),自己创建子协程,如直接使用会出现The app object has not been initialized。合并4.0的相关代码
protected function getSnapshotId($init=false)
{
if ($fd = Context::getData('_fd')) {
return 'fd_' . $fd;
}
if ($init) {
Coroutine::getContext()->offsetSet('#root', true);
return Coroutine::getCid();
} else {
$cid = Coroutine::getCid();
while (!(Coroutine::getContext($cid)->offsetExists('#root'))) {
$cid = Coroutine::getPcid($cid);
if (Coroutine::getContext($cid) == null) {
throw new Exception("发现逃逸协程:$cid");
}
if ($cid < 1) {
break;
}
}
return $cid;
}
}
- 创建一个TestController 执行go([new Test1(),'run']) 然后再Test1类里面执行go([new Test2(),'run']); Test2 run 方法里面new 一个model 然后调用Log::info('xxx'); 即可重现协程逃逸现象,会出现offsetExists on null 的错误,因为自动产生了协程切换。
- 对这种情况,修改getSnapshotId,然后修改initialize 里面清理下即可。4.0依旧有此问题。