mmag

ハマったことメモなど

Erlang 20.1.7でglobal名が衝突してtakeoverが失敗する

www.manning.com

この本を読みながら遊んでいたらハマった。

chuckyというアプリケーションをつくってfailoverとtakeoverを試してみる章で、failoverはうまくいくけどtakeoverできない、という現象が見られた。 A, B, Cという3つのnodeがあり、Aでchuckyが動いているとする。

A [chucky]
B
C

ここでAが死ぬ

🔥
B [chucky]
C

すると、failoverしてBでchuckyが動きはじめる。ここでAが復活すると、本来はtakeoverして以下のようにAでまたchuckyが起動するが、なぜかここがコケる。

A [chucky]
B
C

どのようにコケるかというと、chuckyが立ち上げているプロセスのうちglobalな名前を持っているものが、その名前のプロセスはもう立ち上がっているよ、というエラーで立ち上がれない、というもの。つまり、Aがtakeoverして立ち上がりプロセスにglobalな名前をつけようとしたところで、その名前はBで使われていて落ちる。

回避策として、最初はglobalな名前を付けずに立ち上げて、起動後に:global.re_register_name/2をつかう、とするべきなのかなあと思ったけど、そんなことしないといけないんだっけ、と思って色々試したところ、Erlangのバージョンを今の最新の20.2.2に上げたら本の通りに動いた。失敗していたときはErlang 20.1.7。ちなみにElixirは1.6.0。

原因はよくわかっていないのでもにょり。