我是向来自认为自己是编程高手的。如果又是 Python,我简直是顶尖高手啊!然而,我这“顶尖高手”却被自己坑了一把,还把另一个高手给忽悠了。
这一切,都得从一个 Singleton 说起。
Python 的 Singleton 很容易,不过是
class Singleton:
ob = None
def __new__(cls):
if cls.ob is None:
cls.ob = SomeThing
return cls.ob
然而,我写成了
class Singleton:
connetion = None
def __new__(cls):
if cls.connection is None:
return NewConnection(PoolSize=xxx)
return cls.connection
你看到问题了吗?这根本不会重用啊!!!
这个代码是数据库连接代码,导致每个数据库请求都开启一个新的连接。我一分钟上百上千个左右的请求。数据库连接爆炸。
同事在代码审查时说:“你这个好像不对啊?”
我:Python Singleton 就是这样的。
同事:你确定?
我:我确定,我都 Py 大师了。
同事:好像确实是错的。
我:不不不,你多虑了。
同事:好吧,上线。
我真是系统性大忽悠啊!
如果说这算是智障,接下来还有更智障的。
我其实是有测试的,测试结果显示这个文件的最后一行
return cls.ob
根本没有跑过。但是因为文件小,有93%的覆盖,我就觉得没事,就忽略了!
我靠,该文件总共就这一个class一个方法!其他全是import, 93% 和 50% 一个意思好吗!而且,是整个后端都依赖的代码,很明显得 100% 才行啊。
我居然就忽视了数日,直到数据库爆炸才 debug,而且居然花了 3 个小时!
我去检查各种线程安全性(我们用的 coroutine,根本没有线程),并发安全性,内存问题。。。
MDZZ!
当然,这些无用的检查让我发现了几个部署层面的优化空间。
如何避免
给不同文件模组设定最低测试覆盖率。 比如,关键代码必须100%,中间件95%,用户层代码90%之类的。不同 Layer 的代码的测试要求是不一样的。即使测试都过了,测试覆盖率不达标也算失败。
而且,一定不要人为检查覆盖率,用工具自动化检查,成为 CI 的一部分。