Erlangのsupervisor:start_childで固有のidをChildSpecに渡しているのにalready_startedが返ってきてしまう…という場合に疑うべき凡ミス

Oct 27, 2017 ( Feb 11, 2022 更新 )

要点

  • 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呼び出しでミスってる?と思ってしばらく気づかなかったので、またはまらないように書いておく…。

Return to top