禁用某些构造函数

有时候我们希望用更明确的自定义类型取代一些 primitives,依靠类型系统来减少一些人为错误:

1
2
3
4
5
6
7
void Run(WithMultithreading mt, WithAdvancedMode advanced);

// Both of them work like bool
auto mt = WithMultithreading(true);
auto mode = WithAdvancedMode(false);

Run(mt, mode);

类型 WithMultithraedingWithAdvancedMode 用起来很像 bool,但是他们是两个不同的类型,混用会出现编译错误。

1
Run(mode, mt);  // compile failure; type mis-match

不管我们使用 typedef 还是 using,都只能定义 bool 的类型别名;在类型系统看来他们还是一回事。

Read More

Redigo 源码学习:Pipeline

如何使用 pipeline

先来回顾一下如何在 redigo 中使用 pipeline

1
2
3
4
5
6
7
8
c := pool.Get()
defer c.Close()

c.Send("SET", "foo", "bar")
c.Send("GET", "foo")
c.Flush()
c.Receive() // reply from SET
v, err = c.Receive() // reply from GET

核心是 Send — Flush — Receive 三个步骤。

Read More

Error Handling is Operation Cancellation

最近看了这篇文章有一种顿悟感,想着写点总结加深理解。

如果嫌原文太长可以直接看这篇总结;不过别人咀嚼过的不一定适合你,所以还是推荐一块把原文也看了😁。

Operation Cancellation

假设一个函数 foo() 中的某个操作发生了错误,并且后续操作直接或间接地依赖当前操作的正确行为;那么,不管使用何种错误处理/汇报手段,这里都需要 (1) 中止后续操作并 (2) 向上汇报错误。

这里称这种行为为 operation cancellation

Read More

Python fileinput 换行编码问题

昨晚抽了个时间想修一下 anvil 的这个 issue

根据之前的代码实现,我有 99.99% 的把握换行符被替换成 CRLF 是使用了 fileinput 原地修改了文件导致的。

那段修改的代码的一个等价实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import shutil
import fileinput
import sys

def poc():
orig_name = 'orig.txt'
new_name = 'new.txt'

shutil.copy(orig_name, new_name)

with fileinput.FileInput(new_name, inplace=True) as f:
for line in f:
line = '-> ' + line
print(line, end='')

orig.txt 是一个模板文件,它会被拷贝到指定目录变成一个新文件 new.txt,并修改文件内容。

Read More

Redigo 源码学习:阻塞等待连接可用

通过连接池的设计了解如何回收连接到连接池以及从连接池复用连接后,可以回过头来研究一下 Redigo 支持的阻塞等待可用连接的设计与实现。

通过设置 Pool.Wait == true 之后如果当前连接池满了, Pool.Get() 不会返回连接池耗尽错误,而是阻塞在调用上,直到超时或者存在可用连接才会返回。

这个属于经典的 resource counting 问题,并且最大的 resource count 由 Pool.MaxActive 决定。

Read More

Redigo 源码学习:连接池的设计

主要数据结构

暴露给外部用户的 Pool 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type Pool struct {
...

// Maximum number of idle connections in the pool.
MaxIdle int

// Maximum number of connections allocated by the pool at a given time.
// When zero, there is no limit on the number of connections in the pool.
MaxActive int

// Close connections after remaining idle for this duration. If the value
// is zero, then idle connections are not closed. Applications should set
// the timeout to a value less than the server's timeout.
IdleTimeout time.Duration

mu sync.Mutex // mu protects the following fields
active int // the number of open connections in the pool
idle idleList // idle connections
}

内部维护空闲/待复用的列表数据结构 idleList

Read More

Redigo 源码学习

Redigo 是目前比较流行的一个 Redis Client。

虽然我个人不太喜欢它的 API 设计,奈何这个库简单易用,连公司的 redis 基础库都是在 Redigo 上做的的一个魔改。

注:原生的 Redigo 并不支持 Redis Cluster,某B站的做法是通过 side-car 的方式启动一个 redis proxy 伴生容器,屏蔽 Redis Cluster 的通信细节。

Read More