这是一篇碎碎念,最近有一些想法想分享一下,但是内容又比较简单,不适合写成一篇博客,twitter 又写不下,就一起写一篇博客好了。

首先是上个周做的有关命令行的分享,个人觉得比较满意吧,大家参与的热情也很高,提了不少问题,我自己想说的东西也都分享了。从另外两位讲师的分享中,我自己也学到很多东西。

命令行操作是一个程序员必备的技能。对我来说,写代码是我热爱的事情,我觉得要拿编程作为自己的饭碗(而不是焦虑着如何“在35岁之前转管理”),1)要不断学习新的技术;2)理解这些技术背后的原理更为重要,学习要学到精髓,技术一直在变,但是基本的原理(网络、容器、存储甚至机器学习等)几十年来的变化不大;3)要擅长使用自己的工具。第三点很容易被忽视,但是我觉得是程序员成长路上比较重要的一部分。如果你自己连自己的工具都用不溜,那你很难喜欢自己的编程工作。我见过一些蹩脚的程序员,解压 tar 包都要去网上下载一个解压工具。也难怪想方设法要转管理来脱离编程的“苦海”了。工具的使用不受重视的原因,有一点我觉得是技术氛围是比较受“面试官”导向的。比如面试喜欢问你读过什么源代码,就导致很多人读过各种牛逼项目的源代码,却连文档都没看完;比如面试喜欢问一些“JVM原理”,就造成候选人好像人人都是 Java 专家,却写不好 Java 代码;又比如很多人能回答上来 TCP 一些刁钻的问题,但是却不懂 TCP 的基本原理。面试中很少有人会问你工具如何使用,写一个命令行工具也远不如写一个xxx系统/中间件对面试官来说有吸引力,但是现实是,很多人连“将一个文件夹从一台服务器传到另一台”都做不好。

槽吐完了,流水账一下最近的工作和想法吧。

dbcli 放弃对 Python2 的支持

最近给 pgcli 放弃了对 Python2.7 3.4 3.5 。说实话 pgcli 到现在还能支持这些 Python 版本真够了不起了,但是 prompt-toolkit 3.0 支持的最小 Python 版本是 3.6,所以 pgcli 对这些 python 版本无法继续支持了。如果不升级 prompt-toolkit 到 3.0 的话,一些打包就会 broken。

我本来以为升级工作会很简单,删除这些 Python 版本的测试,添加对 3.8 的测试,然后升级依赖即可。但是遇到的坑实在太深了(可能是我太菜了)。三行代码花了我两个星期,push 了几十次(有些 commits 被 rebase 掉了)。

首先第一个坑是 CPR 的问题,之前以为 pexpect 的 terminal 是 dumb terminal,所以测试没有关闭 CPR 也一直没出过问题,但是升级 prompt-toolkit 这个问题暴露出来了。pexpect 应该是模拟了一个 shell,CPR 没被显式的关闭是有问题的。然后代码库里有个测试写错了,如果我关闭 CPR 这个测试还会挂掉,对发现这个问题的根因造成了极大的干扰。另外所有的测试在 mac 上是完全都能 pass 的,到 Linux 就出问题了(准确的说是在 travis-ci 的 Linux 会出问题,在我的虚拟 fedora 里面就不会),所以只能改代码 push ,让 travis 去测试,非常痛苦。

所以这三行代码背后有我巨大的工作量……

Coverage.py 4.5 对 Python 3.8 的 bug

我添加了 Python3.8 的测试之后,发现覆盖率神奇的下降了好多。一开始以为是 asyncio 的部分使得调度策略变了,导致一部分代码在测试的时候并没有运行?然后仔细看了一下并不是这样,coverage 生成的文件,竟然有一些代码是白色的,不是覆盖也不是未覆盖,成为 Phantom lines 了。然后查了一下,发现是 coverage.py 的问题。升级一下就 ok 了。

后来想了一下,对于已发布版本(向我们这样的)也无法加 warning 提示用户你用的是 Python3.8,只能发新版本,那么旧版本的用户总是会遇到这个坑,从这个 issue 也可以看到这个问题被 link 了无数次了。向前兼容好难啊!

IRedis 新的 feature

最近给 iredis 加 pager 的功能花了不少力气。要对所有的命令兼容 pager,然后要尊重系统的变量,比如 $LESS $PAGER等。prompt-toolkit 输出带颜色的 output 还无法 pipe 到 less,好烦。不过经过重构过一波代码,总算是实现了。再提一句,iredis 代码很多部分经过不同的人重构过,每一次都在变好了,单元测试功不可没啊!

Redis-py extend lock 可以直接接受新值

终于给 redis-py 的 lock 加上这个 feature 了。redis-py 的 lock.extend 语义一直让我很困惑。lock.extend(10) 的意思指的是,让 lock 的 timeout 变成“还剩下的 timeout + 10s”,这就导致我们在多数锁的场景下,这个锁的生命会越来越长,导致 fail over 的速度会来越长。(在这篇文章我有详细描述过)在 redbeat 里面我只能用一个新的 lua 脚本,来保持锁的最大超时时间总是 10s ,不会受之前剩下的 timeout 变得更加长寿。