simplicity is prerequisite for reliability

前些日子我对 Grav Admin 的访问速度感到很不满意,经常打开 Dashboard 页面就给我来个 504 Gateway Timeout,不得不再刷新一次才能正常访问;甚至有一次我在编辑页面写了一大段文字之后,保存失败导致内容丢失,后来尝试再写也没法补全丢失的内容。这份不愉快让我萌生了寻找一个更厉害的博客引擎的念头。

但是基本上 Grav 已经是 2016 年最棒的开源 CMS 了,也就是说综合各个方面因素,没有什么比它更好的 CMS 可供选择。失望之余不免产生想要亲自动手造一个轮子,但是考虑到我已经废弃了原本就不怎么突出的前端能力,如今的我已经对实现一个靠谱的博客后台力不从心,这些冲动最终也只是想想而已。

Read More...

许久之前我分享了一个在 Hexo 博客中制作照片流的方法,至今这个照片流已经成为了我的博客中更新最频繁的页面,承载着我对那些曾经浪费我生命的美好事物的回忆,一开始是书籍和动漫、电影等影视作品,如今还多了个游戏,毕竟游戏继电影之后,也被归为艺术之列,号称「第九艺术」。

我对照片流这个功能是如此的喜爱,以至于我将博客从 Hexo 迁移到 Grav 之后,之前为 Hexo 开发的几个插件都被我放弃了,唯一一个被我移植到 Grav 上的,就是照片流。当然也有一部分原因是移植照片流的工作十分简单,以至于我只需要借助 Twig 模板的宏定义功能就能轻松搞定。

Read More...

要说 2016 年我在技术上的最大的收获,当属心态发生了转变。在此之前,我在技术上没有一个明确钻研方向,为了解决问题嘛,碰到什么问题就搞定什么问题,一时半会搞不定就绕过去,也能获得很好的结果。到头来却是,我成了一个「全栈」工程师,不知道我真实水平的人以为我能力很好,什么烫手山芋交给我都能得到超出预期的好结果。我自己却感觉到彷徨和困惑:几年之后,人们提起我的时候,想到的是一个干活很靠谱的全栈,还是一个别的什么?

Read More...

最近几周一直在魔改一个重要的生产系统,给这个系统加上了一个嵌入式的关系数据库,在内存中缓存一些结构化的数据,使得应用在和数据库之间发生网络隔离的时候也能做一些关键操作。既然是缓存就会涉及到缓存失效、同步、一致性等一系列问题,好在我可以充分利用业务特性来实现最终一致性,但是还是在数据同步上遇到了一个有趣的问题:如何将数据库中有记录被删除这件事情通知到应用,使得缓存中的相关记录也被删除?

Read More...

网易又双叒叕打造了一款厉害的游戏,我自然也不能免俗下载体验了一番这款名为「阴阳师」的「国民手游」,并首次在其中体验了网游氪金的快感。

前些日子我知道这个游戏,但是由于我一直没有玩网游的习惯和精力,也就一直没有想过要体验一番。后来认识的一些朋友开始在社交网络上各种晒姑获鸟,各种吸欧气,看得我心中长草。因为不知道「吸欧气」是什么鬼,我还专门学习了一个提高了姿势水平,还学到了「玄不救非,氪不改命」这句箴言。学习完之后就开始玩阴阳师了,毕竟也想看看自己到底是欧洲人还是非洲人。

Read More...

前些日子欧气爆发,在高可用架构的微博抽奖活动中得到一张 GIAC 的门票,然后我申请了出差,千里迢迢赶赴京师。去年夏天有幸去北京围观 Velocity,姿势水平提高不少,本次 GIAC 请到了多位业界知名的技术大拿,也有不少和我接下来要做的工作相关的主题分享,这些更是提升了我对本次行程的期待。

确定赴京行程后便是约饭,从朋友处得知之另一个朋友拿到了 Google 的 offer,也是个值得庆祝一番的事情。

Read More...

上一篇博文「魔改 pip 的快乐与痛苦」中,我提到魔改开源代码,一个需要时刻考虑的事情,就是如何方便地合并上游变更。为了合并上游变更,我们要尽量克制自己乱写代码的冲动,不要作出那些使得合并代码变得困难重重的事情,比如像我曾经干出的修改包目录的蠢事。

为了修正我犯下的错,我决定在 mpip 代码仓库中保持基本 pip 一样的包目录,改换包目录这种事情放到编译过程里做。于是我不仅要在编译过程里把代码复制一份,还得把包目录从 pip 移动到 mpip,然后把代码里各种和 pip 相关的包目录、文件路径、常量定义、环境变量,总之一切有可能让 pip 和 mpip 之间不清不楚互相干扰的,都得改干净,这样才能让 mpip 和 pip 和平共处。

Read More...

半年前我做了一个 side project,把 pip 魔改一番,使得我能够将 Maven 的 Nexus 仓库作为 pip 的后端仓库。于是原本通过 pip install xxx==version 命令,我们可以从 https://pypi.python.org/simple/ 把指定版本的包下载下来然后安装,我可以用 mpip install xxx==version 从公司内网的 Nexus 仓库下载包然后安装。

之所以做这么个工具,是因为公司没有提供一个内部的 pypi 服务器。Python 不是公司的主流语言,公司自然不会投人力物力去维护这么一个服务,如果由我所在团队自行维护,又得付出额外的人力物力,并不是十分划算。于是我们之前的做法是将系统依赖的三方包,不管是 whl 还是 tgz,直接放在代码目录里,然后在生成部署包的时候再复制、安装。

Read More...

很长一段时间里,我一直以为,对于同一个时间格式,我们把一个时间对象序列化成字符串之后,还能反序列化成和原对象表达同一个时间的时间对象,至少在不考虑时区之类的问题时,这个命题应该成立。

$$ \forall F \in DateFormat, F(D)=S \rightarrow F^{-1}(S)=D $$

然而就在这两天,我遇到了一个打破上述认知的奇怪问题,Date 对象格式化之后再解析回来,就完全乱套了。

Read More...

我使用 Grav 作为博客系统已经好几个月了,基本上还算满意,除了一直没法愉快地在手机上写博客。

Grav 的 Admin 插件是一个功能完善的后台系统,在电脑上的用户体验尤其不错,可以说是我尝试过的各种博客系统中最让我满意的。最让我满意的是它的扩展性,允许用户通过增加 YAML 语法的 blueprint,为系统增加可视化配置编辑页面,靠着这个功能我已经把 Pastime、Links、Author 等页面或者 Sidebar 的内容做成可视化编辑的配置文件,从模板中剥离了。美中不足的是,Admin 插件集成的一个代码编辑器,在移动端输入中文时有致命缺陷。

Read More...