title: Erlang noproc error when trying to terminate child process
body: <p>I tried to design one server to start temporary process when it receives request. However when I tried to terminate or kill the temporary process, I got <code>noproc</code> error. Can anyone tell me how to solve this problem?</p>
  
  <p>I got the following files: </p>
  
  <p>temp.erl (main supervisor)</p>
  
  <pre><code>-module(temp).
  -behaviour(supervisor).
  -export([start_link/0, init/1]).
  -export([list_children/0]).
  
  start_link() -&gt;
      supervisor:start_link({local, ?MODULE}, ?MODULE, []).
  
  list_children() -&gt;
      supervisor:which_children(?MODULE).
  
  init([]) -&gt;
      process_flag(trap_exit, true),
      io:format("****Main supervisor****~n"),
      {ok, {{one_for_one, 5, 10}, 
            [{temp_srv, {temp_srv, start_link, []}, 
              permanent, infinity, worker, [temp_srv]}, 
             {temp_sup, {temp_sup, start_link, []}, 
              permanent, infinity, supervisor, [temp_sup]}]}}.
  </code></pre>
  
  <p>temp_srv.erl (server)</p>
  
  <pre><code>-module(temp_srv).
  -behaviour(gen_server).
  -export([init/1, handle_cast/2, handle_info/2, handle_call/3, terminate/2, code_change/3]).
  -export([start_link/0, echo_call/1]).
  
  -record(state, {}).
  
  -define(SERVER, ?MODULE).
  
  echo_call(Data) -&gt;
      gen_server:call(?SERVER, {echo, Data}).
  
  start_link() -&gt;
      gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
  
  init([]) -&gt;
      process_flag(trap_exit, true),
      {ok, #state{}}.
  
  handle_call({echo, Data}, _From, State) -&gt;
      Result = temp_sup:assign_task({echo, Data}),
      {reply, Result, State};
  handle_call(_Request, _From, State) -&gt;
      {noreply, State}.
  
  handle_info(_Info, State) -&gt;
      {noreply, State}.
  
  handle_cast(_Request, State) -&gt;
      {noreply, State}.
  
  terminate(_Reason, _State) -&gt;
      ok.
  
  code_change(_Old, State, _Extra) -&gt;
      {ok, State}.
  </code></pre>
  
  <p>temp_sup.erl (supervisor to start temporary process)</p>
  
  <pre><code>-module(temp_sup).
  -behaviour(supervisor).
  -export([start_link/0, init/1]).
  -export([start_temp_worker/0, list_children/0, assign_task/1, select_available_children/1, select_finished_children/1]).
  
  start_link() -&gt;
      supervisor:start_link({local, ?MODULE}, ?MODULE, []).
  
  list_children() -&gt;
          supervisor:which_children(?MODULE).
  
  init([]) -&gt;
      io:format("****Temp supervisor*****~n"),
      spawn_link(fun start_pool/0),
      {ok, {{simple_one_for_one, 0, 1}, [{temp_worker, {temp_worker, start_link, []}, temporary, 1000, worker, [temp_worker]}]}}.
  
  start_pool() -&gt;
          [start_temp_worker() || _ &lt;- lists:seq(1, 3)].
  
  start_temp_worker() -&gt;
          supervisor:start_child(?MODULE, []).
  
  assign_task(Data) -&gt;
          case list_children() of
                  [] -&gt;
                          {ok, Pid} = start_temp_worker(),
                          gen_server:call(Pid, Data);
                  ChildL when is_list(ChildL) -&gt;
              case select_finished_children(ChildL) of
                  no_pid_to_kill -&gt; ok;
                  {ok, KPid} -&gt; gen_server:call(KPid, stop)
              end,
              {ok, Pid} = select_available_children(ChildL),
              start_temp_worker(),
              io:format("Assign task to ~p~n", [Pid]),
              gen_server:call(Pid, Data)
          end.
  
  select_available_children([ChildH | ChildT]) -&gt;
      {undefined, Pid, worker, [temp_worker]} = ChildH,
      case gen_server:call(Pid, check_status) of
          active -&gt; 
              io:format("Find available children ~p~n", [Pid]),
              {ok, Pid};
          running -&gt; select_available_children(ChildT);
          done -&gt; select_available_children(ChildT)
      end.
  
  select_finished_children([ChildH | ChildT]) -&gt;
      {undefined, KPid, worker, [temp_worker]} = ChildH,
      case gen_server:call(KPid, check_status) of
          done -&gt; 
              io:format("Find process ~p to kill~n", [KPid]),
              {ok, KPid};
          _ -&gt; select_finished_children(ChildT)
      end;
  select_finished_children([]) -&gt; no_pid_to_kill.
  </code></pre>
  
  <p>temp_worker.erl (temporary process)</p>
  
  <pre><code>-module(temp_worker).
  -behaviour(gen_server).
  -export([start_link/0, init/1]).
  -export([handle_info/2, handle_call/3, handle_cast/2, code_change/3, terminate/2]).
  -record(state, {status}).
  
  start_link() -&gt;
      gen_server:start_link(?MODULE, [], []).
  
  init([]) -&gt;
      process_flag(trap_exit, true),
      io:format("Start temporary worker process ~p~n", [self()]),
      {ok, #state{status = active}}.
  
  handle_info(_Request, State) -&gt;
      {noreply, State}.
  
  handle_call(check_status, _From, #state{status = Status} = State) -&gt;
      {reply, Status, State};
  handle_call({echo, Msg}, _From, State) -&gt;
      io:format("~p get echo request for message ~p~n", [self(), Msg]),
      {reply, Msg, State#state{status = done}};
  handle_call(stop, _From, State) -&gt;
      {stop, normal, stopped, State};
  handle_call(_Request, _From, State) -&gt;
      {noreply, State}.
  
  handle_cast(_Request, State) -&gt;
      {noreply, State}.
  
  code_change(_Old, State, _Extra) -&gt;
      {ok, State}.
  
  terminate(_Reason, _State) -&gt;
      ok.
  </code></pre>
  
  <p>The design is supposed to start three temporary process once the temporary supervisor starts, once it receives request, it will terminate one temporary process which has finished work.</p>
  
  <p>That's how I run these code:</p>
  
  <pre><code>9&gt; temp:start_link().      
  ****Main supervisor****
  ****Temp supervisor*****
  Start temporary worker process &lt;0.98.0&gt;
  {ok,&lt;0.94.0&gt;}
  Start temporary worker process &lt;0.99.0&gt;
  Start temporary worker process &lt;0.101.0&gt;
  10&gt; temp_srv:echo_call(asd).
  Find available children &lt;0.98.0&gt;
  Start temporary worker process &lt;0.102.0&gt;
  Assign task to &lt;0.98.0&gt;
  &lt;0.98.0&gt; get echo request for message asd
  asd
  11&gt; temp_srv:echo_call(asd).
  Find process &lt;0.98.0&gt; to kill
  
  =ERROR REPORT==== 23-May-2017::23:16:34 ===
  ** Generic server temp_srv terminating 
  ** Last message in was {echo,asd}
  ** When Server state == {state}
  ** Reason for termination == 
  ** {{noproc,{gen_server,call,[&lt;0.98.0&gt;,check_status]}},
      [{gen_server,call,2,[{file,"gen_server.erl"},{line,204}]},
       {temp_sup,select_available_children,1,[{file,"temp_sup.erl"},{line,41}]},
       {temp_sup,assign_task,1,[{file,"temp_sup.erl"},{line,33}]},
       {temp_srv,handle_call,3,[{file,"temp_srv.erl"},{line,21}]},
       {gen_server,try_handle_call,4,[{file,"gen_server.erl"},{line,615}]},
       {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,647}]},
       {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}
  
  =ERROR REPORT==== 23-May-2017::23:16:34 ===
  ** Generic server temp terminating 
  ** Last message in was {'EXIT',&lt;0.92.0&gt;,
                             {{{noproc,
                                   {gen_server,call,[&lt;0.98.0&gt;,check_status]}},
                               {gen_server,call,[temp_srv,{echo,asd}]}},
                              [{gen_server,call,2,
                                   [{file,"gen_server.erl"},{line,204}]},
                               {erl_eval,do_apply,6,
                                   [{file,"erl_eval.erl"},{line,674}]},
                               {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
                               {shell,eval_exprs,7,
                                   [{file,"shell.erl"},{line,641}]},
                               {shell,eval_loop,3,
                                   [{file,"shell.erl"},{line,626}]}]}}
  ** When Server state == {state,
                              {local,temp},
                              one_for_one,
                              [{child,&lt;0.96.0&gt;,temp_sup,
                                   {temp_sup,start_link,[]},
                                   permanent,infinity,supervisor,
                                   [temp_sup]},
                               {child,&lt;0.104.0&gt;,temp_srv,
                                   {temp_srv,start_link,[]},
                                   permanent,infinity,worker,
                                   [temp_srv]}],
                              undefined,5,10,
                              [-576459529],
                              0,temp,[]}
  ** Reason for termination == 
  ** {{{noproc,{gen_server,call,[&lt;0.98.0&gt;,check_status]}},
       {gen_server,call,[temp_srv,{echo,asd}]}},
      [{gen_server,call,2,[{file,"gen_server.erl"},{line,204}]},
       {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
       {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
       {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},
       {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}
  ** exception exit: {{noproc,{gen_server,call,[&lt;0.98.0&gt;,check_status]}},
                      {gen_server,call,[temp_srv,{echo,asd}]}}
       in function  gen_server:call/2 (gen_server.erl, line 204)
  </code></pre>