erlang - 为什么 gen_server 超时
问题描述
gen_server
由于我正在处理所有可能的情况,因此我试图弄清楚为什么我的崩溃与超时:
module(wk).
-behaviour(gen_server).
-compile(export_all).
-record(state,{
limit,
count=0,
toSend
}).
start_link(ToSend,Limit)->
gen_server:start_link(?MODULE, {ToSend,Limit}, []).
init({ToSend,Limit})->
State=#state{toSend=ToSend,limit=Limit},
{ok,State}.
handle_call({process,Message},From,State)->
{reply,{processed,os:timestamp()},State};
handle_call(Message,From,State)->
self() ! {from_call,Message},
{noreply,State}.
handle_cast(Message,State=#state{count=C})->
self() ! {from_cast,Message},
{noreply,State}.
handle_info(Message,State=#state{count=C,limit=L,toSend=T})->
io:format("inside handle_info"),
T! {badrequest,Message},
Ret=if C>L -> {stop,State};
_ ->{noreply,State#state{count=C+1}}
end,
Ret.
如您所见,该服务器可以处理许多limit
未知消息,以及cast
消息。现在我的问题是handle_call
:
- 如果我发送一条适合第一种情况的消息,它可以并回复
gen_server:call(S,xx)
当我使用例如发送未知消息时,我收到超时错误:异常退出:{timeout,{gen_server,call,[<0.102.0>,33]}} 在函数 gen_server:call/2 (gen_server.erl,第 215 行)
为什么我的服务器超时?我可以看到handle_call
它进入后handle_info
但为什么会崩溃?
用法:
{ok,Y}=wk:start_link(self(),3).
gen_server:cast(Y,some_message). % works limit times and then crashes as expected
Y ! some_message % works limit times and then crashes as expected
gen_server:call(Y,some_message) % gets inside handle_info , since i get the io message, then times out
解决方案
为什么我的服务器超时?
来自gen_server:call()文档:
call(ServerRef, Request) -> Reply call(ServerRef, Request, Timeout) -> Reply
通过发送请求并等待回复到达或发生超时,对 gen_server 进程的 ServerRef进行同步调用。 …… _
Timeout 是一个大于零的整数,它指定等待回复的毫秒数,或者无限期等待的原子无穷大。默认为 5000。如果在指定时间内没有收到回复,则函数调用失败。
因为您{noreply...}
在handle_call()
函数中选择了返回,gen_server:call()
所以 5 秒后无法返回并超时。您需要手动调用gen_server:reply/2
(在另一个进程中)在超时之前将回复发送回客户端。
推荐阅读
- python - Django Rest 框架 + Django CAS
- javascript - 如果设置了路径,Chrome 会忽略 document.Cookie
- r - R从时间序列中删除最近一周
- java - 使用 RestTemplate 传递 MultipartFile 时,如何解决“No serializer found for class java.io.ByteArrayInputStream”错误?
- java - Apache Open 会议在本地运行以进行开发
- spring - Spring Security:具有角色的用户无法访问端点
- java - 在 Zalenium 上使用自定义配置文件来启用 DRM
- python - Python Logger 异常在 Azure Application Insights (Azure Function) 中记录为跟踪
- python - 使用 Django,我可以重置所有现有记录的主键吗?
- javascript - 在样式化组件 ReactJS 上导入 fonts-face