无知的 TonySeek

Yet Another Seeker

ZooKeeper Session ID 的组成

ZooKeeper 的 Session ID 是每个会话的唯一标识,记录为一个 64 位的长整型。 只要对应会话未被服务器端主动关闭,它就一定能唯一关联上。且会话初次建立时 Session ID 会被写入 transaction log,这意味着会话是跨节点共享的。 客户端和一个节点断开连接后,只要会话还没过期,就仍然可以使用相同的 Session ID 连到另一个节点。这个会话创建的所有临时 ZNodes 也会相应保留。

指标显示 ZooKeeper 经常出现大量 outstanding requests (即节点上排队待处理的请求) 时,我们就需要诊断大量请求来自哪个 ZooKeeper 节点。无论是 leader、follower 还是 observer 节点都在本地处理读请求而将写请求转发给 leader 发起投票,所以节点自身的 outstanding requests 指标可能因参与投票而不是处理本节点的请求而飙高, 从而不一定能准确体现出请求来源。这个时候从 ...

GraphQL vs RESTful API 的一些想法

嗯其实又是一篇早就写了的碎碎念, 在我的 simplenote 里躺了有一年了。也发出来充数吧,好显得我并没有把这个博客弃坑…

GraphQL 出来的时候似乎有老司机说它会“重新定义后端”,当然我们心里知道这实际上是重新定义了重新定义。综合官方文章来看,它要解决的问题都很明确 —— 我认为在 HTTP 1.1 时代它是很有工业价值的。然而它并非唯一的解决方案,RESTful API + HTTP/2 就是一种不错的备选。

Git 中的状态

嗯,这是去年 lttxzmj 初学 Git 的时候写给她的小纸条。两年没写博客了,发出来充个数…

杀死 subprocess.Popen 的子子孙孙

Python 标准库 subprocess.Popen 是 shellout 一个外部进程的首选,它在 Linux/Unix 平台下的实现方式是 fork 产生子进程然后 exec 载入外部可执行程序。

于是问题就来了,如果我们需要一个类似“夹具”的子进程(比如运行 Web 集成测试的时候跑起来的那个被测试 Server), 那么就需要在退出上下文的时候清理现场,也就是结束被跑起来的子进程。

最简单粗暴的做法可以是这样:

process_fixture.py
 @contextlib.contextmanager
 def process_fixture(shell_args):
     proc = subprocess.Popen(shell_args)
     try:
         yield
     finally:
         # 无论是否发生异常,现场都是需要清理的
         proc.terminate()
         proc.wait()


 if __name__ == '__main__':
     with ...

Flask 的 Context 机制

用过 Flask 做 Web 开发的同学应该不会不记得 App Context 和 Request Context 这两个名字——这两个 Context 算是 Flask 中比较特色的设计。[1]

从一个 Flask App 读入配置并启动开始,就进入了 App Context,在其中我们可以访问配置文件、打开资源文件、通过路由规则反向构造 URL。[2] 当一个请求进入开始被处理时,就进入了 Request Context,在其中我们可以访问请求携带的信息,比如 HTTP Method、表单域等。[3]

所以,这两个 Context 也成了 Flask 框架复杂度比较集中的地方,对此有评价认为 Flask 的这种设计比 Django、Tornado ...

Git 忽略某个目录

有时候我们在给开源项目贡献代码的时候,会使用自己熟悉的工具链。比如 Python 项目,我可能就用 tox 来构建发型包并运行单元测试。或者有不习惯用 pyenv 或者 virtualenvwrapper 的同学,就可能直接使用 virtualenv 命令创建一个隔离的环境。

回顾即将结束的 2013 年

2013 年已走向尾声,还有一个小时不到新的一年就要来了。这一年对我来说意义非凡,充满了不同的结束,也充满了不同的开始。

去年偷懒,最后也没写年终总结。2013 年的转折点更多,自己都觉得不记录下来太过分。所以还是流水帐,略记一笔。

为 C/C++ 库定制 Python Binding

这应该是个非常常见的需求了吧。可能因为性能原因需要自己编写一部分 C 代码,可能因为需要的第三方库是 C/C++ 编写的。

我遇到这个问题是因为希望将淘宝发的一个切图实现 tclip 放到 Python 上用。和几个同事都尝试折腾了这个问题,总结出了几种可行的方法。

用装饰器注册 Python 函数

注册回调函数应该是开发中很常见的一种行为。这在 Python 中通常通过装饰器来实现,看起来比较漂亮:

flaskr.py
 @app.route("/")
 def home():
     return "It works."

但是这种用法常常带来一种隐藏的“惊讶”,比如说: