erlang 的错误处理机制非常独特 —— error 的 bubble up 是靠 process 之间的 link 完成的。link 是一个作用域双方互相监视的机制,有点像自战国商鞅变法以降,古代中国常有的保甲连坐制度:一人犯法,连坐者也要受刑。两个 link 起来的 process —— 我们暂且赋予他们名称为小明和小红 —— 如果小明挂了,小红会收到
EXIT
signal,如若不作处理,正常情况下也会挂掉,而小红之死,会进一步触发和小红 link 起来的其他 processes,从而引发和小明有关的整条利益链上的震荡。这便是著名的 let it crash 思想。这种独特的机制让 error handling 实现了真正意义上的 non-local:一切与其相关的 process,都会受其影响,就像是对待癌细胞一样,除非有对症的法子,否则相关的细胞统统杀死,绝不姑息。反观其他语言的 error handling,与其说是 handling,不如说是 hide —— 就像边关报急,烽火连天,兵部却将其压下,回报圣上天下太平,然后马照跑,舞照跳。
link 是双向的连坐机制,有时候对于一些影响不大的问题,我们并不需要如此强有力的手段,于是有了 monitor。monitor 像是战场上的斥候,监视一个 process 的异动,一旦有变,立即回禀一个消息。收到消息的 process 可以选择按兵不动,或者随机应变。
erlang/OTP 的 supervision tree 就是基于 link/monitor 这样非常简单的机制构建起来的。而之所以 erlang 可以任性的 let it crash,其中一个很大的原因是 process 非常轻量,构建和销毁的代价无非就是创建和回收若干个 C structs。