[erlang-questions] Mysterious gen_server timeouts in MIX

Vance Shipley vances@REDACTED
Sat Nov 2 10:45:11 CET 2013


On Fri, Nov 01, 2013 at 09:21:29PM -0700, John R. Ashmun wrote:
}  sometimes running using application:start( 'MIX' ) and sometimes booting
}  MIX as an Erlang release -- sometimes compiling using +debug_info (or not)
}  has seemed to change from success to failure (or, equally likely, the
}  opposite).

If your program is correct it's just too busy to respond before the
timeout.  In my experience however when you get to the point where a
message roundtrip is over 5 seconds you are in bad design territory.

You may have a race condition.  You say you have several gen_server
behaviour processes communicating with each other.  Hopefully this
communication is accomplished asynchronously.  Whenever you use a
receive statement, which you effectively do when you call a function
like gen_server:call/2, your process stops being a generic behaviour
until the call is completed.  No system messages or any others will
be processed during this time.

Here is an example of a pathological program which will eventually
deadlock:

-module(race).
-export([init/1, handle_info/2, handle_call/3, terminate/2]).
-record(state, {name, count}).

init([Name]) ->
	State = #state{name = Name, count = 0},
	random:seed(now()),
	Timeout = random:uniform(4000) + 1000,
	{ok, State, Timeout}.

handle_info(timeout, #state{name = Name, count = Count} = State) ->
	NewCount = gen_server:call(Name, Count),
	{noreply, State#state{count = NewCount}, random:uniform(1000)}.

handle_call(N, _From, State) ->
	{reply, N + 1, State, 0}.

terminate(_Reason, _State) ->
	ok.

Run it like this:

     1> gen_server:start({local, ping}, race, [pong], []),
     1> gen_server:start({local, pong}, race, [ping], []).
     {ok,<0.35.0>}

... and some time later:

     =ERROR REPORT==== 2-Nov-2013::14:47:10 ===
     ** Generic server pong terminating 
     ** Last message in was timeout
     ** When Server state == {state,ping,103446400}
     ** Reason for termination == 
     ** {timeout,{gen_server,call,[ping,103446400]}}
     
     =ERROR REPORT==== 2-Nov-2013::14:48:55 ===
     ** Generic server ping terminating 
     ** Last message in was timeout
     ** When Server state == {state,pong,103446400}
     ** Reason for termination == 
     ** {{timeout,{gen_server,call,[ping,103446400]}},
         {gen_server,call,[pong,103446400]}}

Here the processes have called each other a hundred million times
before deadlocking.

-- 
	-Vance




More information about the erlang-questions mailing list