I use gun as a http client in my application and use opened connections to handle multiple requests.
It usually works ok, but recently my application stoped handling requests and it turned out that gun connections processes have lists of unhandled messages in their mailboxes, like this:
rp(process_info(<0.31175.48>, messages)).
{messages,[{'$gen_cast',{request,<0.11099.53>,
#Ref<0.3234177338.3490709505.118665>,<<"POST">>,
<<"/v1/topic/get">>,
[{<<"content-type">>,<<"application/json">>}],
<<"{}">>,infinity}},
{'$gen_cast',{request,<0.12338.53>,
#Ref<0.3234177338.3095658499.71403>,<<"POST">>,
<<"/v1/topic/get">>,
[{<<"content-type">>,<<"application/json">>}],
<<"{}">>,infinity}}]}
And every new request just adds a new message to that mailbox.
I’ve looked into gun’s code and I see that it should handle such messages with no problem in ‘connected’ state, here is the line from gun:
connected(cast, {request, ReplyTo, StreamRef, Method, Path, Headers, Body, InitialFlow},
State=#state{origin_host=Host, origin_port=Port,
protocol=Protocol, protocol_state=ProtoState, cookie_store=CookieStore0,
event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
{Commands, CookieStore, EvHandlerState} = Protocol:request(ProtoState,
dereference_stream_ref(StreamRef, State), ReplyTo,
Method, Host, Port, Path, Headers, Body,
InitialFlow, CookieStore0, EvHandler, EvHandlerState0),
commands(Commands, State#state{cookie_store=CookieStore,
event_handler_state=EvHandlerState});
I tried to see the status of that connection process (with big timeout just in case) :
sys:get_status(<0.31175.48>, 600000).
But it didn’t work, I’ve just found the new system message in gun’s connection process mailbox:
{system,{<0.22180.130>,#Ref<0.3234177338.4042522626.87030>}, get_status}
So I can’t find out what state is this gen_statem server is in and I don’t know what caused it to switch into this state from ‘connected’ state.
The process_info looks like this:
process_info(<0.31175.48>).
[{current_function,{gen,do_call,4}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,8},
{links,[<0.1197.0>]},
{dictionary,[{'$initial_call',{gun,init,1}},
{'$ancestors',[gun_conns_sup,gun_sup,<0.1195.0>]}]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.1194.0>},
{total_heap_size,8370},
{heap_size,4185},
{stack_size,63},
{reductions,1402917},
{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,6}]},
{suspending,[]}]
The protocol used by connection is http2 and secure layer is on.
So I’m stuck and I can’t figure out reasons why that could happen. I’m sure that this process was in state ‘connected’ because I stored it’s pid in my pool of connections when the connection was established.
Has anybody experienced similar problems with gun (the connection process is alive but all requests through this connection fail) and have any advice on what can be done to figure out and solve the problem?