[erlang-questions] gen_statem is blocking in gen do_call, a lot of messages does not be handled.

Raimo Niskanen raimo+erlang-questions@REDACTED
Fri May 4 15:40:24 CEST 2018


On Fri, May 04, 2018 at 03:51:45PM +0800, getonga wrote:
> The process info is 
> ```
> process_info(pid(0, 818, 0)).                                
> [{current_function,{gen,do_call,4}},                                                 
>  {initial_call,{proc_lib,init_p,5}},                                                                                 
>  {status,waiting},                                                                   
>  {message_queue_len,10},                                                
>  {messages,[1,2,3,3,4,5,6,7,8,9,10]},               
>  {links,[<0.514.0>,<0.1294.0>]},                                                     
>  {dictionary,[{rand_seed,{#{bits => 58,jump => #Fun<rand.8.15449617>,                
>                             next => #Fun<rand.5.15449617>,type => exrop,             
>                             uniform => #Fun<rand.6.15449617>,           
>                             uniform_n => #Fun<rand.7.15449617>,weak_low_bits => 1},
>                           [218965415455180470|167242355698640157]}},               
>               {'$initial_call',{time_server,init,1}},                                
>               {'$ancestors',[time_sup,app_sup,<0.512.0>]}]},
>  {trap_exit,true},
>  {error_handler,error_handler},
>  {priority,normal},
>  {group_leader,<0.511.0>},
>  {total_heap_size,987},
>  {heap_size,987},
>  {stack_size,47},
>  {reductions,27674},
>  {garbage_collection,[{max_heap_size,#{error_logger => true,kill => true,size => 0}},
>                       {min_bin_vheap_size,46422},
>                       {min_heap_size,233},
>                       {fullsweep_after,65535},
>                       {minor_gcs,0}]},
>  {suspending,[]}]
> 
> ```

If you have a gen_statem server that from its event handler calls some
other server via gen:do_call, e.g from gen_server:call, and that call hangs
there is nothing the calling server can do about it.

Do not make blocking calls from an event handler!
That will prevent the server from processing it's message queue.
Find out why the called server is blocked.
You may have two servers calling each other which is a way to create
deadlock...


> 
> 
> and I look into the gen_statem.erl code, the gen:call/4 is running without timeout:
> ```
> call_dirty(ServerRef, Request, Timeout, T) ->                                                                                                                                                                                                 
>     try gen:call(ServerRef, '$gen_call', Request, T) of
>         {ok,Reply} ->
>             Reply
>     catch
>         Class:Reason ->
>             erlang:raise(
>               Class,
>               {Reason,{?MODULE,call,[ServerRef,Request,Timeout]}},
>               erlang:get_stacktrace())
>     end.
> 
> ```

I do not know where you are getting with this, but the argument T contains
the timeout time.  The argument Timeout is only used when raising an error
to fake (with the right arguments) that it was gen_statem:call/3
that caused the exception.


> 
> 
> Is the code blocks my gen_statem process ? How can I disable it?

Do not do blocking calls from an event handler!
-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list