2016-12-05 13 views
0

プロセスの状態を10秒タイマーで更新しようとしています。私がやりたいことはだから私はタイマーでPIDを更新するにはどうすればよいですか?

handle_info(trigger, _State) -> 
    land:action(self(), {fight}), 
    erlang:send_after(?INTERVAL, self(), trigger); 

を試みるが、私は、エラーメッセージが何も存在しないことを意味し

=ERROR REPORT==== 4-Dec-2016::19:00:35 === 
** Generic server <0.400.0> terminating 
** Last message in was trigger 
** When Server state == {{dict,0,16,16,8,80,48, 
           {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], 
           []}, 
           {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], 
           []}}}, 
         []} 
** Reason for termination == 
** {function_clause,[{land,terminate, 
          [{timeout,{gen_server,call,[<0.400.0>,{fight}]}}, 
          {{dict,0,16,16,8,80,48, 
            {[],[],[],[],[],[],[],[],[],[],[],[],[],[], 
            [],[]}, 
            {{[],[],[],[],[],[],[],[],[],[],[],[],[], 
            [],[],[]}}}, 
          []}], 
          [{file,"src/land.erl"},{line,47}]} 

答えて

0

を取得し、この

handle_call({fight}, _From, Temple) -> 
    NewTemple = temple:fight(Temple), 
    {reply, NewTemple, NewTemple}; 

を呼んで

-define(INTERVAL, 3000). 

start_link() -> 
    gen_server:start_link(?MODULE, [], []). 

action(Pid, Action) -> 
    gen_server:call(Pid, Action). 

init([]) -> 
    erlang:send_after(?INTERVAL, self(), trigger), 
    {ok, temple:new()}. 

terminate土地servの条項あなたが土地サーバーモジュールをコンパイルするときに警告を発するべきです。

terminate句が呼び出されました。これは、という行をland:action(self(), {fight}),という名前で呼び出してgen_server呼び出し中にタイムアウトが発生したために呼び出されます。 gen_serverへの呼び出しは最大時間内に完了する必要があります。デフォルトは5000msです。あなたは戦闘アクションに費やされた時間を短縮する必要があります。

gen_server呼び出しがブロックされているため、サーバータイムアウトを増やすことはお勧めしません。gen_server呼び出しの実行中に新しいメッセージを処理することはできません。また、あなたの例では、 handle_info(trigger, _State)コード。

最後の点では、の文節は{noreply,NewState}のタプルを返し、最後の行erlang:send_after(?INTERVAL, self(), trigger);はタイマー参照を返します。この行は修正する必要があります。

1

land:action(self(), {fight})で、現在triggerメッセージを処理している同じgen_serverにcallを作成しようとしています。これがうまくいかない理由を2つの重要な事実が説明します:

  • callは結果が返されるのを常に待ちます。
  • gen_serverはプロセスであり、プロセスは一度に1つのメッセージしか処理できません。 triggerメッセージの処理に

、あなたが戻って自分自身にcallに言って、自分が{fight}メッセージを処理するのを待ちます。あなたはtriggerメッセージを処理する途中にいるので、{fight}というメッセージは表示されません。あなたは効果的にあなた自身とデッドロックしています。だからあなたはタイムアウトを得ている。

P.S. SSCCEを投稿すると、あなたに良い答えが得られる可能性が非常に高くなります。

関連する問題