2011-03-30 88 views
2

我在嘗試瞭解這裏發生了什麼:主管在重新啓動孩子時是否阻止呼叫?

我有一位主管在不觸發MaxR, MaxT機制的情況下循環重新啓動一個客戶端。客戶端崩潰足夠慢,從不觸發速率限制。

有會一直使用supervisor:which_children/1delete_child/2, start_child/2相適應的一套兒童的現實另一個機制(其爲USB設備掃描試圖讓每發現一個設備監孩子)。

這通常會像限制安全網一樣,但奇怪的是,它看起來像刪除和啓動兒童的機制根本沒有被調用。

要了解發生了什麼,我從shell中調用了supervisor:which_children/1,它看起來像調用只是阻止並且從不返回。

是否可以在主管嘗試重新啓動孩子時阻止對主管的呼叫?

附錄:

它看起來像崩潰孩子開始時發生的情況:

=SUPERVISOR REPORT==== 29-Mar-2011::21:36:20 === 
    Supervisor: {local,gateway_sup} 
    Context: start_error 
    Reason:  {'EXIT',{timeout,{gen_server,call,[<0.155.0>,late_init]}}} 
    Offender: [{pid,<0.76.0>}, 
       {name,gw_3_5}, 
       {mfa,{channel,start_link, 
          [[{gateways,[{left,108},{right,103}]}], 
          {3,5}]}}, 
       {restart_type,transient}, 
       {shutdown,10000}, 
       {child_type,worker}] 
+0

你在孩子的'start_link'函數中做了'gen_server:call'嗎? – 2011-03-30 11:24:36

+0

是的,我願意。我需要在gen_server已經運行之後進行一些遲的初始化。 – 2011-03-30 11:37:22

+0

爲什麼不在'init'函數中執行此操作?似乎這裏可能存在死鎖的風險...... – 2011-03-30 11:51:44

回答

1

的問題的答案除了討論:

當重新啓動過程中發生故障的孩子啓動監督程序在其進程內部(它是一個gen_server內部)不處理任何API調用。

因此,如果將超級用戶的速率限制配置爲不會觸發孩子的啓動錯誤,那麼這一點尤其糟糕。在我的例子中,我有一個緩慢的啓動(特別是在錯誤)。

因此,如果監督者永遠循環嘗試重新啓動一個孩子,那麼對於任何對它的調用都是無法訪問的......這通常是不好的。

+1

最好的辦法是爭取儘可能簡單的初始化階段,並在進程啓動後完成其餘部分。這樣做的好處是雙重的,首先,主管儘可能少地參與(而不是被阻止,因爲你已經發現許多重啓和初始階段很長的情況),其次這個過程受到主管監控開始(如果在後面的設置中出現問題,則由主管處理)。 – 2011-03-31 07:22:37

+0

阿門!我對複雜的'init'回調(啓動其他進程,讀取文件等)有一些非常不愉快的經歷。 – gregorej 2011-05-31 09:14:24