首页 > 解决方案 > 为什么 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

为什么我的服务器超时?我可以看到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

标签: erlangerlang-otpgen-server

解决方案


为什么我的服务器超时?

来自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(在另一个进程中)在超时之前将回复发送回客户端。


推荐阅读