New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DI并发获取, 存在协程切换 可能会获取到不同实例 #5116
base: master
Are you sure you want to change the base?
Conversation
src/di/src/Container.php
Outdated
if (isset($this->resolvedEntries[$id]) || array_key_exists($id, $this->resolvedEntries)) { | ||
return $this->resolvedEntries[$id]; | ||
} | ||
Coroutine::sleep(0.001); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里可以改为用 usleep
为啥不用协程锁? |
建议改成用channel广播,即有一个协程在获取中时,将标志位置为true,如果此时有更多的协程也需要获取,就去创建channel,首个获取协程返回时,如果检查到有其它等待获取的协程(即channel被创建了),就往这个channel里push获取到的对象直到channel没有订阅者。 或者,后来的协程使用yield挂起,并记录到一个队列里,当第一个获取的协程获取完成后,挨个去resume那些等待的协程。 总之,sleep的轮询检查的方式非常低效,而且很不优雅。 |
在框架启动时 ,Di组件 没有在协程环境 |
Swow下没有非协程环境,主协程和其它手动创建的协程都是平等关系; |
这里不能改,di 读取不能增加协程逻辑,对 di 来说这就是一个对象,如果你把 io 扔到了构造函数里,就算这里改了,其他地方用的时候也还是有相同的问题。 |
比如一下第三方的组件, 构造函数可能存在io; 这样改 可以确定 获取到的是同一个实例 其他地方是指哪方面呢? |
如果 构造函数里有 io 的类,你就在进程启动后,立马进行初始化就行了 |
他是担心有些组件构造函数里有IO, 但是他自己也不清楚; |
swoole channel有可能阻塞,而且和swoole版本有关,非常奇怪 |
最近看到这个文章 https://blog.csdn.net/lqb3732842/article/details/126559432
测试了一下, 并发下获取类, 可能出现获取到不同实例
测试类
普通类
结果
修复后 正常