I have a locally registered gen_server [1], which traping exits and
monitoring list of processes (which saved in ETS table in it's state).
The priority of this gen_server set to high.
We also use fullsweep_after = 0.
The only job of this gen_server is to spawn gen_servers of other type
and update ETS table with their pids.
The priority of a spawned gen_server process is normal.
For some reason the message queue length of this gen_server start
increasing, whith messages which supposedly should processed by
gen_server:handle_info/2 [2].
Any ideas?
[2]
(mynode@myhost)9> whereis(myserver).
<0.194.0>
(mynode@myhost)10> i(0,194,0).
[{registered_name,myserver},
{current_function,{proc_lib,sync_wait,2}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,43388},
{messages,[{'EXIT',<0.17263.1>,normal},
{'DOWN',#Ref<0.0.220.23782>,process,<0.17263.1>,normal},
{'EXIT',<0.19870.0>,normal},
{'DOWN',#Ref<0.0.7.128134>,process,<0.19870.0>,normal},
{'EXIT',<0.19945.0>,normal},
{'DOWN',#Ref<0.0.7.183474>,process,<0.19945.0>,normal},
{'EXIT',<0.19927.0>,normal},
{'DOWN',#Ref<0.0.7.166242>,process,<0.19927.0>,normal},
{'EXIT',<0.19847.0>,normal},
{'DOWN',#Ref<0.0.7.119123>,process,<0.19847.0>,normal},
{'EXIT',<0.19935.0>,normal},
{'DOWN',#Ref<0.0.7.174779>,process,<0.19935.0>,normal},
{'EXIT',<0.17267.1>,normal},
{'DOWN',#Ref<0.0.220.24915>,process,<0.17267.1>,normal},
{'EXIT',<0.19833.0>,normal},
{'DOWN',#Ref<0.0.7.109092>,process,<0.19833.0>,normal},
{'EXIT',<0.19895.0>,normal},
{'DOWN',#Ref<0.0.7.135024>,process,...},
{'EXIT',<0.19906.0>,...},
{'DOWN',...},
{...}|...]},
{links,[<0.14463.0>,<0.1452.1>,<0.28537.1>,<0.6041.2>,
<0.11523.2>,<0.13320.2>,<0.13691.2>,<0.14031.2>,<0.14312.2>,
<0.14363.2>,<0.14502.2>,<0.14514.2>,<0.14518.2>,<0.14523.2>,
<0.14516.2>,<0.14509.2>,<0.14512.2>,<0.14506.2>,<0.14471.2>,
<0.14490.2>|...]},
{dictionary,[{'$ancestors',[router_core_sup,router_sup,
<0.189.0>]},
{'$initial_call',{myserver,init,1}}]},
{trap_exit,true},
{error_handler,error_handler},
{priority,high},
{group_leader,<0.188.0>},
{total_heap_size,1346269},
{heap_size,1346269},
{stack_size,26},
{reductions,3818768},
{garbage_collection,[{min_bin_vheap_size,46368},
{min_heap_size,233},
{fullsweep_after,0},
{minor_gcs,0}]},
{suspending,[]}]
--------------------------------------
[1]
-module(myserver).
-behaviour(gen_server).
...
handle_info({'EXIT', Pid, _}, State) ->
delete_by_pid(Pid, State),
{noreply, State};
handle_info({'DOWN', _, process, Pid, _}, State) ->
delete_by_pid(Pid, State),
{noreply, State};
handle_info(Info, State) ->
{stop, {unknown_info, Info}, State}.
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
> erlang-questi...@erlang.orghttp://erlang.org/mailman/listinfo/erlang-questions
Allen
delete_by_pid(Pid, State) -> case ets:lookup(State#state.pid2id,
Pid) of [{_, ID, Ref}] -> erlang:demonitor(Ref),
ets:delete(State#state.pid2id, Pid),
ets:delete(State#state.id2pid, ID); _ -> ignore
end.
On Nov 3, 11:21 pm, Allen Kim <allen....@epicadvertising.com> wrote:
> from my limited knowledge, it seems your delete_by_pid/1 is waiting for
> something.
>
> Allen
>
> erlang-questi...@erlang.orghttp://erlang.org/mailman/listinfo/erlang-questions
delete_by_pid(Pid, State) ->
case ets:lookup(State#state.pid2id, Pid) of
[{_, ID, Ref}] ->
erlang:demonitor(Ref),
ets:delete(State#state.pid2id, Pid),
ets:delete(State#state.id2pid, ID);
_ ->
ignore
end.
Allen
>erlang-q...@erlang.org
>http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
It is not ok to let a gen_server delete itself because it is not guaranteed to delete the reference associated with it from the shared table. This approach will leak memory unless the child processes don't exit under ideal conditions.
There is also one possible issue with your server which is that you are starting the child processes directly from the same server receiving the EXIT and DOWN messages. In the process info you included you can see that the current function is proc_lib:sync_wait, this call happens to be inefficient on processes with large inboxes, it'll likely turn out to be much more of a bottleneck than the ETS calls in delete_by_pid.