기본적으로 gen_server 호출 (및 gen_fsm)의 시간 제한은 5 초입니다. 콜백 함수는 이유로 너무 오래, 서버 충돌 지속되면
{timeout,{gen_server,call,[GenServerPid,LastMessage]}}
그것은하지 않습니다 캐스트 기능, 동시에 아웃 (콜백 즉시 반환하기 때문에 내가 추측)가 보인다 있지만, 콜백 실행에 의해 차단 된 경우 다음 호출이 실패하게됩니다. 응용 프로그램이
(두 번째 메시지의 부족이 오류 상태임을 고려한다면 즉) 메시지가 콜백하는 동안 곧 도착할 것을 요구하지 않는
그래서 나는 그것이 좋은 아이디어라고 생각하지 않습니다
-module (tout).
-behaviour(gen_server).
-define(SERVER, ?MODULE).
%% export interfaces
-export([start_link/0,call/2,cast/2]).
%% export callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
%% INTERFACES %%
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
call(Pid,Time) ->
gen_server:call(Pid,{wait,Time}).
cast(Pid,Time) ->
gen_server:cast(Pid,{wait,Time}).
%% CALLBACK FUNCTIONS %%
init([]) ->
{ok, #{}}.
handle_call({wait,Time}, _From, State) ->
timer:sleep(Time),
{reply, done, State};
handle_call(_Request, _From, State) ->
{reply, {error, unknown_call}, State}.
handle_cast({wait,Time}, State) ->
timer:sleep(Time),
{noreply, State};
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% LOCAL FUNCTIONS %%
셸 세션 :
1> c(tout).
{ok,tout}
2> tout:start_link().
{ok,<0.136.0>}
3> tout:call(tout,500).
done
4> tout:call(tout,5100).
** exception exit: {timeout,{gen_server,call,[tout,{wait,5100}]}}
in function gen_server:call/2 (gen_server.erl, line 204)
5> tout:start_link().
{ok,<0.141.0>}
6> tout:cast(tout,10000).
ok
7> tout:cast(tout,1000).
ok
8> % wait a little .
8> tout:call(tout,100).
done
9> tout:cast(tout,10000).
ok
10> % no wait .
11> tout:call(tout,100).
** exception exit: {timeout,{gen_server,call,[tout,{wait,100}]}}
in function gen_server:call/2 (gen_server.erl, line 204)
12>
[편집]다음 코드를 확인 예 선택적 수신는 gen_fsm 불가능하고 일반적인 문제는 다음과 같습니다
FSM은 STATE_1에 있으며 state_2로 이동하라는 메시지가 다음 도착하기 직전, state_2에서 처리해야하는 메시지 수신 :
을
- 이 첫 번째 메시지는 state_1에서 처리해야합니다. 그렇지 않으면 프로세스가 충돌합니다.
- 이 메시지는 사서함에서 제거되며 fsm이 State2로 전환 할 때 여기에 없으므로 응용 프로그램은이 위험을 관리해야합니다. 하나의 프로세스에 의해 올바른 순서로 2 개의 메시지를 전송함으로써 상황을 파악할 수 있습니다.
이 문제는 프로세스가 gen_fsm 코드를 실행하는 동안이 문제가 2 콜백 사이에 표시되므로 콜백 중 하나의 수신 블록에서 해결할 수 없습니다.
내가는 R19에서 오는 새로운 행동 gen_statem 해결해야 할 문제 중 하나입니다 생각 handle_call
에서 receive
을 사용하고 다른 콜백 이유
제 경우에는 gen_server에 대한 호출이 없으며 모든 작업은 캐스트를 통해 수행됩니다. 타임 아웃에 대해 옳은 것 같아요. 그렇다고해서 저자가 그렇게 말하는 이유는 아닌 것 같습니다. –
답변을 수정했습니다. – Pascal