由于erlang超时,如何触发handle_info?
How to trigger handle_info due to timeout in erlang?
我正在使用 gen_server 行为并试图了解如何从 handle_call
中出现的 timeout
触发 handle_info/2
例如:
-module(server).
-export([init/1,handle_call/3,handle_info/2,terminate/2).
-export([start/0,stop/0]).
init(Data)->
{ok,33}.
start()->
gen_server:start_link(?MODULE,?MODULE,[]).
stop(Pid)->
gen_server:stop(Pid).
handle_call(Request,From,State)->
Return={reply,State,State,5000},
Return.
handle_info(Request,State)->
{stop,Reason,State}.
terminate(Reason,State)->
{ok,S}=file:file_open("D:/Erlang/Supervisor/err.txt",[read,write]),
io:format(S,"~s~n",[Reason]),
ok.
我想做什么:
我原以为如果我启动服务器并且不会在 5
秒内使用 gen_server:call/2
(在我的情况下),那么 handle_info
将被调用,这将依次发出stop
从而调用 terminate
。
我看到它不会以这种方式发生,事实上 handle_info
根本没有被调用。
例如 this i see the timeout
is set in the return of init/1
.
What I can deduce is that it handle_info
gets triggered only if I initialize the server and issue nothing (nor cast
nor call
for N
seconds).If so why I can provide Timeout
in the return
of both handle_cast/2 and handle_call/3 ?
更新:
我试图获得以下功能:
- 如果
X
秒内没有发出call
触发handle_info/2
- 如果
Y
秒内没有发出cast
触发handle_info/2
我认为这个超时可以在handle_call
和handle_cast
的return
中设置:
{reply,Reply,State,X} //for call
{noreply,State,Y} //for cast
如果不是,那么这些超时是什么时候触发的,因为它们是 returns
?
要从 gen_server:handle_call/3
回调启动超时处理,必须首先调用此回调。你的Return={reply,State,State,5000},
根本没有执行。
相反,如果你想“启动服务器并且不会使用 gen_server:call/2
5 秒然后 handle_info/2
将被调用”,你可能 return {ok,State,Timeout}
来自 gen_server:init/1
回调的元组。
init(Data)->
{ok,33,5000}.
您不能为不同的 调用和转换设置不同的超时。正如 Alexey Romanov 在评论中所述,
Having different timeouts for different types of messages just isn’t something any gen_*
behavior does and would have to be simulated by maintaining them inside state.
如果一个returns {reply,State,Timeout}
元组来自任何handle_call/3
/handle_cast/2
,如果[=21]后此进程的邮箱为空,将触发超时=].
我建议你阅读源代码 code:gen_server.erl
% gen_server.erl
% line 400
loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
after Time ->
timeout
end,
decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
帮助您理解参数Timeout
我正在使用 gen_server 行为并试图了解如何从 handle_call
中出现的 timeout
触发 handle_info/2
例如:
-module(server).
-export([init/1,handle_call/3,handle_info/2,terminate/2).
-export([start/0,stop/0]).
init(Data)->
{ok,33}.
start()->
gen_server:start_link(?MODULE,?MODULE,[]).
stop(Pid)->
gen_server:stop(Pid).
handle_call(Request,From,State)->
Return={reply,State,State,5000},
Return.
handle_info(Request,State)->
{stop,Reason,State}.
terminate(Reason,State)->
{ok,S}=file:file_open("D:/Erlang/Supervisor/err.txt",[read,write]),
io:format(S,"~s~n",[Reason]),
ok.
我想做什么:
我原以为如果我启动服务器并且不会在 5
秒内使用 gen_server:call/2
(在我的情况下),那么 handle_info
将被调用,这将依次发出stop
从而调用 terminate
。
我看到它不会以这种方式发生,事实上 handle_info
根本没有被调用。
例如 this i see the timeout
is set in the return of init/1
.
What I can deduce is that it handle_info
gets triggered only if I initialize the server and issue nothing (nor cast
nor call
for N
seconds).If so why I can provide Timeout
in the return
of both handle_cast/2 and handle_call/3 ?
更新:
我试图获得以下功能:
- 如果
X
秒内没有发出call
触发handle_info/2
- 如果
Y
秒内没有发出cast
触发handle_info/2
我认为这个超时可以在handle_call
和handle_cast
的return
中设置:
{reply,Reply,State,X} //for call
{noreply,State,Y} //for cast
如果不是,那么这些超时是什么时候触发的,因为它们是 returns
?
要从 gen_server:handle_call/3
回调启动超时处理,必须首先调用此回调。你的Return={reply,State,State,5000},
根本没有执行。
相反,如果你想“启动服务器并且不会使用 gen_server:call/2
5 秒然后 handle_info/2
将被调用”,你可能 return {ok,State,Timeout}
来自 gen_server:init/1
回调的元组。
init(Data)->
{ok,33,5000}.
您不能为不同的 调用和转换设置不同的超时。正如 Alexey Romanov 在评论中所述,
Having different timeouts for different types of messages just isn’t something any
gen_*
behavior does and would have to be simulated by maintaining them inside state.
如果一个returns {reply,State,Timeout}
元组来自任何handle_call/3
/handle_cast/2
,如果[=21]后此进程的邮箱为空,将触发超时=].
我建议你阅读源代码 code:gen_server.erl
% gen_server.erl
% line 400
loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
after Time ->
timeout
end,
decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
帮助您理解参数Timeout