2010-12-08 10 views
2

gen_serverのinit部分に実行時エラーがあります。 - initはprocess_flag(trap_exit、true)で始まります - gen_serverは監視ツリーの一部です terminateモジュールで理由を表示しようとしましたが、別の場所で終了するようです。 - なぜterminateが呼び出されないのですか? アプリケーションは、シャットダウンを理由として停止します。 - ランタイムエラーをどのようにキャッチするのですか?gen_serverとランタイムエラー

+0

いくつかのコードを入力してください。 –

+0

まず第一に、それは一般的な質問です! – Bertaud

+2

質問は一般的ですが、あなたの考えは正しいです。通常、 'terminate'が呼び出されます。これが人々がコードを求める理由です。 –

答えて

4

通常、この状況でコールバックが呼び出されます。つまり、出口が閉じ込められているためです。

これが当てはまらない唯一の場所は、init関数でクラッシュが発生した場合です。その場合、その責任は監督者にあり、監督者は通常その結果として終結する。次に、このエラーは、アプリケーション全体を終了させるまでスーパーバイザツリーをクロールします。

通常、スーパーバイザはコンテキストをstart_errorに設定してスーパーバイザレポートを記録します。これは、監督ツリーの一部には対処すべき問題があるというあなたのヒントです。エラーが発生する場所について間違った前提があるかもしれないので、これを確認してください。

はあなたの問題はあなたがすべてでSASLについて知らないということですHERE

から編集します。それを勉強する。これを使用する方法の例を次に示します。あなたの例から

掲揚コード:

まず、我々はgen_serverを持っているのErlangを伝えるために必要なbahlonga。

-module(foo). 
-behaviour(gen_server). 
-export([start_link/0]). 
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 
    terminate/2, code_change/3]). 

それはあなたのコード

-record(state, { name, port, socket_listen }). 

基本start_linkageで使用することができるように、我々は#state {}レコードをハック...

start_link() -> 
    gen_server:start_link({local, foo}, ?MODULE, [], []). 

あなたのinit関数、スポーンの問題が含まれています。私たちの上

init([]) -> 
    Port = 3252, 
    Name = "foo", 

不足している機能のための

process_flag(trap_exit, true), 
    erlang:error(blabla), 
    Opts = [binary, {reuseaddr, true}, 
     {backlog,5}, {packet, 0}, {active, false}, {nodelay, true}], 
    case gen_tcp:listen(Port,Opts) of 
    {ok,Socket_Listen} -> 
     logger:fmsg("--> [~s,init] Socket_Listen crée = ~p", 
      [Name,Socket_Listen]), 
     {ok,handle_accept(#state{socket_listen=Socket_Listen})}; 
    {error, Reason} -> 
     logger:fmsg("--> [~s,init] Erreur, Raison =~p", 
      [Name,Reason]), {stop, Reason} 
    end. 

ハックは....

handle_accept(_) -> 
    #state{}. 

残りはちょうど基本です...簡略化のためのビットをハッキングしてきました。 ..、私はそれらを省略します。 foo_supfooのための監督のために今

-module(foo_sup). 
-behaviour(supervisor). 
-export([start_link/0]). 
-export([init/1]). 
-define(SERVER, ?MODULE). 

基本開始リンク...

start_link() -> 
    supervisor:start_link({local, ?SERVER}, ?MODULE, []). 

基本ChildSpec。 fooの子を立ち上げて実行する...

init([]) -> 
    FooCh = {foo, {foo, start_link, []}, 
     permanent, 2000, worker, [foo]}, 
    {ok, {{one_for_all,0,1}, [FooCh]}}. 

SASL有効にしてブートアーラン:

[email protected]:~$ erl -boot start_sasl 
Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] 

=PROGRESS REPORT==== 9-Dec-2010::01:01:51 === 
[..] 
Eshell V5.8.3 (abort with ^G) 

1> foo_sup:start_link(). 
...私たちは監督を起動してみましょうそして、私たちはこの取得:上記

=CRASH REPORT==== 9-Dec-2010::01:05:48 === 
    crasher: 
    initial call: foo:init/1 
    pid: <0.58.0> 
    registered_name: [] 
    exception exit: {blabla,[{foo,init,1}, 
          {gen_server,init_it,6}, 
          {proc_lib,init_p_do_apply,3}]} 

をにクラッシュがあることがわかります例外のためblablaです。

 in function gen_server:init_it/6 
    ancestors: [foo_sup,<0.45.0>] 
    messages: [] 
    links: [<0.57.0>] 
    dictionary: [] 
    trap_exit: true 
    status: running 
    heap_size: 233 
    stack_size: 24 
    reductions: 108 
    neighbours: 

これでスーパーバイザが問題について報告します。私はそれが...

 Reason:  {blabla,[{foo,init,1}, 
          {gen_server,init_it,6}, 
          {proc_lib,init_p_do_apply,3}]} 

、期待される理由になるだろうと述べて

=SUPERVISOR REPORT==== 9-Dec-2010::01:05:48 === 
    Supervisor: {local,foo_sup} 
    Context: start_error 

コンテキストはまさにです。

 Offender: [{pid,undefined}, 
        {name,foo}, 
        {mfargs,{foo,start_link,[]}}, 
        {restart_type,permanent}, 
        {shutdown,2000}, 
        {child_type,worker}] 
+0

私はinitでerlang:error(blabla)でランタイムエラーをエミュレートしていますが、私はスーパーバイザでblablaを見たことがありません! – Bertaud

+0

それからコードを見る必要があります。 –

+0

INIT(状態=#状態{ポート=ポートは、名前=名}) - > process_flag(trap_exit、真)、 アーラン:エラー(blabla)、 OPTS = [バイナリ、 {REUSEADDR、真}、 {バックログ、5}、 {パケット、0}、} {活性偽、 {NODELAY、真}]、\t \t ケースgen_tcp:試聴(ポート、OPTS) \t {OK、Socket_Listen}の - > \tロガー:fmsg( " - > [〜s、init] Socket_Listencrée=〜p"、[Name、Socket_Listen])、 \t \t {ok、handle_accept(state#state {socket_listen = Socket_Listen})}; \t \t \t {エラー理由} - > \t \tロガー:fmsg( " - >〜S、INIT] Erreur、レゾン=〜P"、[名]、[理由])、 {停止理由} \t終了。 – Bertaud