我带的实习生要开始搞 fpm 的落地和实现了,为了更加优雅的完成这个工具,整个 rpmbuild – Test – Beta – Production 生命周期充斥着各类异步场景。

0x00 Promise in Node.js

这段时间写大屏用 Node.js 积累了一些网络和文件操作上使用异步编程的经验,一般简单场景使用回调方式就能很好的解决问题,但当遇到比较复杂的逻辑时,为了避免 Callback Hell 的问题的,异步接口更好的处理办法就是使用 Promise 接口。

let promisify = (fn, receiver) => {
  return (...args) => {
    return new Promise((resolve, reject) => {
      fn.apply(receiver, [...args, (err, res) => {
        return err ? reject(err) : resolve(res);
      }]);
    });
  };
};

var fs = require("fs");
var readFilePromise = promisify(fs.readFile, fs); // Encapsulate Promise interface

readFilePromise("foo.json", "utf8").then(function(content){
    // normal
}).catch(function(err){
    // abnormal
})

题外话,JavaScript 从 ES8 开始支持基于 Promise 的 Async/Await 语法糖, 实现类似 Golang 协程采用同步方式写异步代码。

Continue reading

最近听了 IoT 长连接 Erlang 研发同学的技术分享,部分分享内容涉及到到了 HTTP/2,刚好在草稿箱里翻到了两年前攒的这篇文章,趁这个机会补充一下把他放出来吧。

HTTP/2 不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。

0x00 HTTP Frames

HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”(frame):头信息帧和数据帧。

HTTP/2 相较于 HTTP/1.* 的不同点在于,HTTP/2 将 HTTP 协议通信分解为二进制编码Frame的交换,这些Frame对应着特定Stream中的Message。所有这些都在一个 TCP 连接内复用。这是 HTTP/2 协议所有其他功能和性能优化的基础。

二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。

Frame 的基础结构由五部分组成:

  • Length: 表示 Frame Payload 的大小,是一个 24-bit 的整型,表明 Frame Payload 的大小不应该超过 2^24 – 1 byte,但其实 payload 默认的大小是不超过 2^14 byte,可以通过 SETTING Frame 来设置 SETTINGS_MAX_FRAME_SIZE 修改允许的 Payload 大小;
  • Type: 表示 Frame 的类型,目前定义了 0-9 共 10 种类型;
  • Flags: 为一些特定类型的 Frame 预留的标志位,比如 Header, Data, Setting, Ping 等,都会用到;
  • R: 1-bit 的保留位,目前没用,值必须为 0;
  • Stream Identifier: Steam 的 id 标识,表明 id 的范围只能为 0 到 2^31 – 1 之间,其中 0 用来传输控制信息,比如 Setting, Ping;客户端发起的 Stream id 必须为奇数,服务端发起的 Stream id 必须为偶数;并且每次建立新 Stream 的时候,id 必须比上一次的建立的 Stream 的 id 大;当在一个连接里,如果无限建立 Stream,最后 id 大于 2^31 时,必须从新建立 TCP 连接,来发送请求。如果是服务端的 Stream id 超过上限,需要对客户端发送一个 GOWAY 的 Frame 来强制客户端重新发起连接。

Continue reading

昨晚快下班的时候,蓝色港湾那家影院的客服小哥给我打电话说我们预定的那个包场被取消了,心态有点炸。今早到公司重新规划了路线,终于把周五 Building 的全套行程都确定下来了,明天消费升级改道去国贸。

中午有小姐姐来找我说他们新员工培训抽到了‘持续创新’的主题,打算把我做 AI 沟通助手的过程拍成一部 VCR,于是我们很愉快的聊了下研发细节,话说上次涉足演艺圈事业已经是快一年前的事了,明少当时约了一票好友一起造了一晚上,记得那时候坐我左手边的姑娘气质特别好,唱霉霉的歌也特有感觉。


转眼间接口开放平台野蛮生长了很长一段时间了,一直没有一个很正式的测试环境,每次做新需求都是从 git 上把代码拉下来重新起套新环境,这里面存在很多坑,比如 Python3 版本升级之后 virtualenv 中的 mysql 依赖就装不上了

ModuleNotFoundError: No module named 'ConfigParser'

查阅相关文档之后发现在 Python3 版本升级后,ConfigParser.py 已经更名为 configparser.py 了,可以同前版本的处理办法一样,通过重命名解决问题,但是路子太野会给之后上量扩容满坑,所以得找找其他办法。

https://github.com/PyMySQL/PyMySQL

于是我找到了 mysql 的替代模块 PyMySQL,

pip3 install PyMySQL

如果还有报错,那么:

# Ubuntu
sudo apt-get install libmysqlclient-dev

# CentOS
sudo yum install python-dev mariadb-devel

PyMySQL 的玩儿法也更加优雅,特别对于多条数据的处理逻辑也更加线性易于理解。Continue reading