为什么 gen_server 超时
Why does gen_server get timeout
我正在尝试找出为什么我的 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
Why is my server timing out ?
来自 gen_server:call() 文档:
call(ServerRef, Request) -> Reply
call(ServerRef, Request, Timeout) -> Reply
Makes a synchronous call to the ServerRef of the gen_server process by
sending a request and waiting until a reply arrives or a time-out
occurs.
...
...
Timeout is an integer greater than zero that specifies how many
milliseconds to wait for a reply, or the atom infinity to wait
indefinitely. Defaults to 5000. If no reply is received within the
specified time, the function call fails.
因为您在 handle_call()
函数中选择 return {noreply...}
,gen_server:call()
不能 return 并在 5 秒后超时。需要在超时前手动调用gen_server:reply/2
(在另一个进程中)向客户端发送回复。
这里发生了一些事情。
您正在从 GenServer 内部向 self() 发送消息,这些消息将被发送到 GenServer。这些消息需要在 handle_info 块中处理,我没有看到实现,所以在这一点上,一切都被视为错误请求。
其次,您正在通过您保持状态的 Pid/Name 将消息发送回 caller/caster,只要您使用类似 {回复,"processing call",State},因为你使用了 noreply,你的呼叫超时,因为它已经说明了。通常,您不想立即使用 returns 某事的调用,但如果您需要确认流程已完成工作并正在处理它,这可能是一种很好的责任交接机制。否则,如果它是一个同步调用,请使用 gen_server:reply 而不是 T !消息语法,但您必须以不同方式对待调用和转换。
祝你好运
客户端超时。一旦调用 gen_server:call/2 的第二个子句,客户端仍在等待响应,该响应永远不会被发回。
我正在尝试找出为什么我的 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
Why is my server timing out ?
来自 gen_server:call() 文档:
call(ServerRef, Request) -> Reply call(ServerRef, Request, Timeout) -> Reply
Makes a synchronous call to the ServerRef of the gen_server process by sending a request and waiting until a reply arrives or a time-out occurs.
...
...Timeout is an integer greater than zero that specifies how many milliseconds to wait for a reply, or the atom infinity to wait indefinitely. Defaults to 5000. If no reply is received within the specified time, the function call fails.
因为您在 handle_call()
函数中选择 return {noreply...}
,gen_server:call()
不能 return 并在 5 秒后超时。需要在超时前手动调用gen_server:reply/2
(在另一个进程中)向客户端发送回复。
这里发生了一些事情。
您正在从 GenServer 内部向 self() 发送消息,这些消息将被发送到 GenServer。这些消息需要在 handle_info 块中处理,我没有看到实现,所以在这一点上,一切都被视为错误请求。
其次,您正在通过您保持状态的 Pid/Name 将消息发送回 caller/caster,只要您使用类似 {回复,"processing call",State},因为你使用了 noreply,你的呼叫超时,因为它已经说明了。通常,您不想立即使用 returns 某事的调用,但如果您需要确认流程已完成工作并正在处理它,这可能是一种很好的责任交接机制。否则,如果它是一个同步调用,请使用 gen_server:reply 而不是 T !消息语法,但您必须以不同方式对待调用和转换。
祝你好运
客户端超时。一旦调用 gen_server:call/2 的第二个子句,客户端仍在等待响应,该响应永远不会被发回。