@
2225377fjs 你认为 gevent 是优雅的高效的产物,而我想告诉你实际上他只是一个没有办法的将就。
首先,关于讨论,
技术或者项目经验存在高低,是否能意识到 gevent 存在的问题都无所谓,我们可以慢慢交流。
但是你希望还是可以认识到没有进行充分的论证,指责他人的工作毫无意义是一件很没有礼貌的事情。
另外,措辞体现一个人的素质,尊重这件事情也是相互的,于人于己应该都是有利的。
说他是将就,是因为:
* gevent 会给项目带来毁灭性的隐患,且无法预料
* 不区分协程函数和普通函数(不使用 yield )是一个很糟糕的习惯
* 侵入式的兼容只能产生一个不可知的过渡用品,而不是一个有保障的产品
所以需要非基于 gevent 的重新实现:
* 他不会给程序埋下无法发现的隐患
* 他使用了更好的协程习惯
* 他每一个方法都有保障,不会充满了不可知
我的观点里有一个大局,一个细节。
说大局,
主要是希望你把我放在一个同等的位置上听一下我说的话,讨论才能有意义。
把我当成一个一无所知的跳梁小丑的话,可能你也提不起兴致和我交流。
当然,如果你可以拿出你的项目让我认同,我也不介意自己以跳梁小丑的身份虚心求教。
以我浅薄的见识看到的大局里,我不是一个人固执己见倾向于使用 yield 等关键字。
和你讲一下我看到的大局,那些大牛都是怎么看待 gevent 的。
Python 之父明确表明过 gevent 不是一个好的实现
你可以在他的 Twitter 里看到:
https://twitter.com/gvanrossum/status/443093650533142528gevent 早已出现,而加入标准库的是 asyncio 而非 gevent 更是对这一态度的明确实践。
Requests 的作者对于本类项目的期待是我写这个项目的初衷。
Requests 的作者一直认为使用 gevent 不是一个好的做法,他多次在 grequests 的 issue 中提出希望有基于 Future 和 yield 语法的协程 Requests。
例如 Issue#10 和 Issue#51,他提出这是一个好的想法,但是他没有时间实现。
( Issue#10: suggestion: use concurrent.futures instead of gevent 中他这样说道:
I'm 100% for this now — i've been talking about it for a few months now. Just need to implement ;))
在 gevent 和其他的基于 yield 的协程的选择中,他百分百的站在了 gevent 的对立面。
不说国外,国内学习 Python 多多少少听说过董伟明,特别是 Web 开发一块。
他在个人的博客中明确表明:所以建议大家放弃 Gevent,拥抱 asyncio。
(
http://www.dongwm.com/archives/使用 Python 进行并发编程-我为什么不喜欢 Gevent/)
说细节,
是希望我们可以在讨论中把优劣讨论的越来越清楚。
我就回复开始的三个点一个一个解释:
关于隐患,先上一个特别简单的代码:
import multiprocessing, grequests; manager = multiprocessing.Manager()
他报错了,如果不是这段代码非常简单的只有一个引用,你需要多久要怎么发现是 gevent 的问题?
另外,这个问题你需要怎么修复?
所以就有了很多报出 gevent 毁了他整个项目的情况:
https://github.com/kennethreitz/grequests/issues/55,https://github.com/pytest-dev/pytest-xdist/issues/254不仅如此,关于垃圾回收,gevent 也会导致问题:
https://www.projectcalico.org/the-sharp-edges-of-gevent/更不要说一些操作的误区,例如使用 RLock,却发现明明都是主线程却没法锁两次。
使用 gevent 你难免会陷入是不是 gevent 又出问题了和完全没有修理的头绪的噩梦当中。
所以我说 gevent 是一颗定时炸弹,而我的项目不是,所以我认为我的项目有意义。
关于习惯,
董伟明关于习惯有一段话说得很好,我就不画蛇添足了:
Gvanrossum 说用它就是” patch-and-pray ”,太形象了。
由于 Gevent 直接修改标准库里面大部分的阻塞式系统调用,包括 socket、ssl、threading 和 select 等模块,而变为协作式运行。
但是我们无法保证你在复杂的生产环境中有哪些地方使用这些标准库会由于打了补丁而出现奇怪的问题,那么你只能祈祷( pray )了。
在 Python 之禅中明确说过:「 Explicit is better than implicit.」,猴子补丁明显的背离了这个原则。
我认可这个观点,即使仅是为了服务持有这个观点的这些人,我也认为我的项目有意义。
关于三方库,
你说 gevent 最大的一个优势就是可以与很多现有库兼容,api 也非常干净,我同意。
gevent 通过侵入式的修改让一些三方库直接可用,这很棒。
但这只是不可预知的部分可用,例如 Requests,你了解哪些部分是无法像预期那样表现的吗?
另外,这些部分哪些是可以修复的,哪些是框架所限无法修复的呢?
所以才需要一个让 Requests 所有部分功能都明确可用的库才出现。
你提到了很多外部系统,本项目基于 tornado,你可以将这些和 tornado 或者 asyncio 进行配对搜索,你就能发现全都有相应支持。
反观 gevent,kafka 的支持我并不认可 Github 上那个仅有 11 Star 长久未更新的项目,rabbitmq、zookeeper 之流更是不堪。
我不满足于不可预知的部分可用,所以我认为这个项目有意义。
当然还有一点是效率,
你并没有证明你所提出的相对于其他协程解决方案的高效,这里提一下,希望可以在后面的交流中看到。
另外,在证明的时候还是希望可以考虑到 gevent 对于 Python 解释器的限制。
最后,感谢你的时间,也期待你的回复!