IRedis 1.0 发布

这算是 IRedis 开发系列的第4篇笔记吧。这篇文章来聊一下 IRedis 最近发布 1.0 带来的新 Feature,一些开发过程中的思考,以及最后贴一下发布之后的一些“成就” (炫耀)。上次提到的介绍一些开发中使用的 tricks,就让我再拖到下一篇博客吧!

PS: 如果您还不知道 IRedis 的话,可以理解成是 redis-cli 的一个替代品。类似于 IPython 相比于 python 官方的 REPL,专注于用户体验,支持语法高亮,命令提示,自动补全等。全部的 Feature 可以参考项目 Readme,以及官网。

New Features

Changelog 是从 0.8 开始记录的,这里说一下几个两点功能:

支持了 Peek 命令,用 Redis 的时候不需要先用 type 看一下 key 的类型,然后再去选择对应的命令来操作了;

支持了配置文件 ~/.iredisrc.

支持了 Redis 所有的命令,支持了时间戳补全(没有人想在命令行输入时间戳!),支持了 int 类型补全。(我发现实现补全器很有意思呢!)

更多的功能演示 gif 可以见这个页面

Coming Features

  1. 支持用 URL 来传入 Redis 连接参数,比如 iredis --url redis://username:[email protected]:6379/5 lyqsmy 正在实现这个 Feature
  2. 支持通过 alias_dsn 连接 redis,比如把上面这个 url 保存在 ~/.iredisrc 里面,然后在命令行通过 iredis --dsn main 去连接。
  3. 将 IRedis 打包成单个文件,通过 curl 就可以下载到机器上执行。目前采用的方案是 PyOxidizer,遇到不少问题,mac-chaffee 正在做这项工作

开发思考

最想分享的是单元测试了,开发一个又一个Feature的时候,测试挂了 N 多次,每次挂了我都庆幸一次幸亏写了测试。分享一下 piglei 的文章,以及我在评论里留下的一些想法:

我也想分享一些有关测试的想法。我很喜欢写测试,最近在写的 https://github.com/laixinta… 搞了一年多,测试挂了无数次。测试这个事情很反直觉的一点是,你觉得测试会增加开发成本,而事实相反。我知道我的测试覆盖了哪些地方,所以,我可以放心大胆的重构,主要测试pass了,我就敢发布新版本。随着代码越写越多,开发效率一点也没有降低,有什么新功能直接写就行了,之间的函数抽象不够直接重构,然后修复测试。这个项目到今天还是能保持着只要合并了master就可以作为新的feature立即发布,甚至我的发布流程也是交给CI的,我只要打tag push就好了。

另外有几点感受:

  1. 写稳定的测试是很重要的,有时候我们会因为assert 的list顺序不一样而导致测试随机挂掉,一定要找到原因,保持测试的可信度;
  2. 稳定的CI服务很重要,我从 circleCI 换到travis,现在用Github Action,CircleCI因为自身问题挂过3次,travis从没挂过,Github挂过1次(目前),如果CI变成“这次挂了,但可能不是我的问题,我要re-run试试”,体验是很糟糕的;
    CI的速度很重要。现在有200+测试,刚开始需要5min在CI跑完,后来我对venv加了cache,测试3个Python版本只要1min了;
  3. 覆盖率不重要。盲目追求100%是没有意义的。比如有些代码你写了 re.match("xxx", str) 你知道这个正则需要match很多种情况,但是其实只要你写1种,对覆盖率检测来说,它就以为你覆盖了,但其实需要更多的case来发现问题。还有一种情况,在函数的入口做参数检查,比如两个 kwargs 不能同时出现,这种代码很难出错,其实没必要测试(当然写一个也就几行)。所以,我现在觉得100%的测试覆盖并不能说明一个库是质量好的,覆盖率70%也并不能说明这个库测试不够完全;
  4. 应该一开始就写测试。以前我的想法是先写好功能,写的完善了,到1.0了,再开始写测试。这种想法是不对的,应该在POC的时候就写POC的测试,这样可以保证开发质量,和开发效率。有一个额外的好处是,这时候的测试可以作为样例代码,供用户或同事参考。
  5. 我觉得理想的开发团队(虽然我没遇到过)应该用测试来保护自己的代码,如果别人修改了我的部分,并且全通过了我的测试,但是引入了BUG,那我会认为是我的责任。

—— on 《游戏《蔚蓝山》教我的编程道理

另外,我发现 Python 里面的 Generator 很容易被忽略。

第一种情况是很容易忽略很多内置的函数返回的是 Generator,只能迭代一次。比如我在写 Completer 的时候写过的下面这个代码:

导致这个 Completer 只在第一次使用的时候有用,这个现象很奇怪,我花了几十分钟才意识到这 reversed() 返回的不是 list,只是 generator,只能用一次。

另外情况就是一个函数很长,中间出现了一个 yield,就从一个 function 变成 generator maker 了(我觉得很多地方搞混了“生成器”和“生成器 maker”,def foo(): yield "hello" 这其实不是 generator,只是制造出 generator 的一个东西,每次调用都会出现一个新的 generator,所以我把它叫做 generator maker)。然后现象也很奇怪,就是这个函数根本没跑。找了好久才找到原来是没用 next() 激活。

说到底,说他“坑”的原因就是这种情况完全不会报错,不会有任何错误,完全隐藏在了程序的逻辑中。很难排查。


以下是发布之后受到的关注:

1.0 之后我在 Hackernews 贴了一下,但是一直都没什么人,感觉在 HN 发帖子很难受到关注,结果第二天起床一看,竟然被顶上了首页:

上Top10了, 没有截图到,放个Twitter吧

还没有写完的时候,RedisWatch就推荐过一次,80期

被 RedisWatch 第二次推荐 (第84期)

还有两个哥们跟我说他们在微博看到有人转发我的项目了,开心

PyCoders推荐了

本来想让DB Weekly推荐一下的,但我还没联系他们,下一期就出来了,封面竟然是IRedis!

IRedis的Itamar的评价

prompt-toolkit 作者的评价



IRedis 1.0 发布”已经有13条评论

      • 但是会出现一个问题, 没有redis-cli的-c参数, 我的请求命令似乎不能分发到集群节点, 执行scan后访问的是随机不同节点的key

        • 是的,iredis 的集群模式是默认开启的,所以没有 -c 参数。但是只实现了 follow MOVED 基本的功能。

          redis-cli 的行为可以具体描述下吗?我用的不多,也许可以在 iredis 里面也实现一下,谢谢。

回复 davidfeng 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注