我正在使用 gen_server 行为并试图了解如何 handle_info/2
从 timeout
触发发生在 handle_call
例如:
-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.
我想做什么:
我期望如果我启动服务器并且不会使用 gen_server:call/2
对于 5
秒(在我的例子中)然后 handle_info
将被调用,这将依次发出 stop
因此调用terminate
.
我看到它不会以这种方式发生,事实上 handle_info
根本没有被调用。
在诸如 this 的示例中我看到 timeout
在 init/1
的返回中设置.
我可以推断出它handle_info
只有当我初始化服务器并且什么都不发出时才会触发(cast
和call
持续N
秒)。如果是这样,为什么我可以提供Timeout
在return
两者的 handle_cast/2和 handle_call/3 ?
更新:
我试图获得以下功能:
- 如果没有
call
发表于X
秒触发器handle_info/2
- 如果没有
cast
发表于Y
秒触发器handle_info/2
我认为这个超时可以在 return
中设置的 handle_call
和 handle_cast
:
{reply,Reply,State,X} //for call
{noreply,State,Y} //for cast
如果不是,那么这些超时是什么时候触发的,因为它们是 returns
?
最佳答案
从gen_server:handle_call/3
开始超时处理回调,必须首先调用此回调。您的 Return={reply,State,State,5000},
根本没有执行。
相反,如果你想“启动服务器并且在 5 秒内不使用 gen_server:call/2
然后 handle_info/2
将被调用”,你可能从 gen_server:init/1
返回 {ok,State,Timeout}
元组回调。
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.
如果从任何 handle_call/3
/handle_cast/2
返回 {reply,State,Timeout}
元组,超时将被触发如果此进程的邮箱在 Timeout
后为空。
关于server - 由于erlang超时,如何触发handle_info?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59559517/