2012-11-15 59 views
1

我有一個由gen_servers作爲臨時子女的監督樹,其壽命很短。當需要清理和終止時,每個孩子都會收到一條消息。單獨終止simple_one_for_one子女

從我從tinymq項目中讀取的代碼的啓發下,有一個控制器進程可以保存這些孩子的Pid字典。

在他們的情況下,他們使用max_age設置過期他們的頻道與一些code我不太明白。

在我的情況下,我嘗試使用supervisor:terminate_child(Sup, Pid),後做一些清理,具體如下:

孩子本身,確實控制器上的RPC:

fs_outbound_controller:deallocate_me(UUID, self()); 

控制器:

deallocate_me(UUID, Pid) -> 
    gen_server:cast(?SERVER, {deallocate_me, UUID, Pid}). 

handle_cast({deallocate_me, UUID, Pid}, #state{dict = Uuid2Pid} = State) -> 
    NewDict = dict:erase(UUID, Uuid2Pid), 
    supervisor:terminate_child(fs_outbound_extn_sup, Pid), 
    error_logger:info_msg("Successfully deallocated ~p", [UUID]), 
    {noreply, State#state{dict=NewDict}}. 

我觀察到的問題是,錯誤記錄器報告崩潰關於gen_server終止返回值?

** Reason for termination == 
** {bad_return_value,ok} 

您的幫助表示讚賞。

編輯

我沒有別的東西,我搬到調用RPC從從孩子到控制器deallocate_me郵件。考慮到也許孩子對控制器進行RPC調用,結果導致一些回報問題。該處理程序仍然是相同的

handle_info({deallocate_me,UUID,PID},{#state字典= Uuid2Pid} =狀態) - > NewDict =字典:擦除(UUID,Uuid2Pid) 監:terminate_child(fs_outbound_extn_sup, Pid), error_logger:info_msg(「成功解除分配〜p」,[UUID]), {noreply,State#state {dict = NewDict}}。

但還是現在我得到:

** Reason for termination == 
** {bad_return_value,{deallocate_me,"49d9f7cb-62d3-4c3f-abf1-a19848967a9a", 
            <0.50.0>}} 

回答

0

這似乎對我來說

fs_outbound_controller:deallocate_me(UUID, self()); 

被稱爲無論是handle_call/3handle_cast/2handle_info/2內的最後一條語句。正如你可能知道的那樣,這些期望類似{reply, ...},{noreply, ...}{stop, ...}

請記住,gen_server:cast/2總是返回okServerPid ! Message始終返回Message本身。這就是爲什麼你第一次被告知{bad_return_value, ok},第二次是{bad_return_value, MessageSent}

在你的情況我會堅持gen_server:cast方式簡單地把正確的返回值錯誤的電話之後:

fs_outbound_controller:deallocate_me(UUID, self()), 
{noreply, State}; %% strongly depends on what your logic there is 
+0

嗨@Keynslug你釘它,作爲一個驕傲的二郎山小白我完全忘了回報'handle_info/2'的值。使用RPC調用發送異步消息的原因是什麼? – lfurrea

+0

@ifurrea,'gen_server:cast'不是一個rpc調用,它也是一個簡單的異步消息傳遞,除此之外,您還可以遵循'gen_server'約定,並且可以確保您收到的轉換來自已知的發件人。與任何人都可以通過無導向的方式發送的簡明信息相比。 – Keynslug