[erlang-questions] gen_server:call/3 and timeout handling

Robert Raschke rtrlists@REDACTED
Thu Dec 3 11:15:21 CET 2009


On Wed, Dec 2, 2009 at 10:48 PM, zabrane Mikael <zabrane3@REDACTED> wrote:

> When I use the call "gen_server:call/3 (I mean using the timeout option),
> a timout may occur if the corresponding  "gen_server:handle_call/3" takes
> take too long.
> Then, the whole "gen_server" crashes with an error report.
>
>
> What I'd like to achieve is  to "intercept" this "timeout" message in my
> "gen_server" code and handle
> it gracefully without stopping my "gen_server" (eg. by sending back a reply
> with reason = timeout).
>
> Is this possible? Is there a best practice for that?
>
>
I think you would need to wrap the call in a try-catch, as the function call
itself is failing due to the timeout.

For example, using this dummy server:

-module(timeout_test).
-behaviour(gen_server).

-export([start_link/0, test/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3,
terminate/2]).

start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
test() -> gen_server:call(?MODULE, test, 1000).

init([]) -> {ok, []}.

handle_call(test, _From, State) -> {reply, timer:sleep(1500), State}.

handle_cast(_Request, State) -> {noreply, State}.
handle_info(_, State) -> {noreply, State}.
code_change(_Old, State, _Extra) -> {ok, State}.
terminate(_Reason, _State) -> ok.


And in the shell:

Eshell V5.6.5  (abort with ^G)
1> c(timeout_test).
{ok,timeout_test}
2> timeout_test:start_link().
{ok,<0.27047.4>}
3> try timeout_test:test() catch Error:Reason -> {Error, Reason} end.
{exit,{timeout,{gen_server,call,[timeout_test,test,1000]}}}
4>

You can obviously also put the try-catch into the function that does the
gen_server:call and return interesting values depending on the catch.

Hope this gets you in the right direction,
Robby


More information about the erlang-questions mailing list