要点
- supervisor:start_childでalready_startedが返ってくるときは、supervisorのchildとしてのidが固有かだけでなくworkerのidが固有かの検証に失敗している場合がある
- 手癖で書いてないでちゃんと確認する
凡ミス内容
one_for_one
でsupervisorを書いて、いざsupervisor:start_child
したら、最初の1件のchild以外{error, already_started}
が返ってきてしまった。
supervisor:start_child(sup, ChildSpec),
%% {{already_started,<0.670.0> ...
このときchildspecのidには固有の値を指定していたので、なんでだろう…と思ってたけど、よく見たらworkerとして起動させるgen_server:start_linkに固定のidを渡してしまっていた。
-spec(start_link(Param :: binary()) ->
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
start_link(Param) ->
%% テンプレ生成しててうっかり?MODULEのままにしていた
gen_server:start_link({local, ?MODULE}, ?MODULE, [Param], []).
-spec(start_link(Name :: atom(), Param :: binary()) ->
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
start_link(Name, Param) ->
%% こんな感じでNameをとるか、勝手に名前がつくようにする?
gen_server:start_link({local, Name}, ?MODULE, [Param], []).
凡ミスだけど、workerとして動かすほうのidの衝突もまとめられてsupervisor側でalready_started
とされるので
supervisorのAPI呼び出しでミスってる?と思ってしばらく気づかなかったので、またはまらないように書いておく…。