[erlang-questions] UDP concurrent server
Fred Hebert
mononcqc@REDACTED
Wed Dec 9 17:13:24 CET 2015
On 12/09, Bogdan Andu wrote:
>init([Port, Ip]) ->
> process_flag(trap_exit, true),
>
> {ok, Sock} = gen_udp:open(Port, [binary,
> {active, false},
> {reuseaddr, true},
> {ip, Ip}
> ]),
>
> {ok, #udp_conn_state{sock = Sock}, 0}.
>handle_info({udp, Socket, Host, Port, Bin}, State) ->
> {noreply, State, 1};
>
>handle_info(timeout, #udp_conn_state{sock = Sock} = State) ->
> inet:setopts(Sock, [{active, once}]),
> {noreply, State};
>
>handle_info(Info, State) ->
> {noreply, State}.
>
Uh, interesting. So one thing I'd change early would be to go:
handle_info({udp, Socket, Host, Port, Bin}, State=#udp_conn_state{sock = Sock}) ->
inet:setopts(Sock, [{active,once}]),
{noreply, State};
(and do the same in `init/1')
This at least would let yo consume information much faster by avoiding
manual 1 ms sleeps everywhere. Even a `0' value may help. It doesn't
explain the leaking at all though.
What would explain it is that if you're not matching the message (as in
your original email), then you never set the socket to 'active' again,
and you never receive traffic.
If that's the problem, then you have been measuring a process that
receives traffic to a process that does not. It certainly would explain
the bad behaviour you've seen.
If you want to try to see if a garbage collection would help, you can
try the 'recon' library and call 'recon:bin_leak(10)' and it will take a
snapshot, run a GC on all processes, then return you those that lost the
most memory. If yours is in there, then adding 'hibernate' calls from
time to time (say, every 10,000 packets) could help keep things clean.
It sucks, but that might be what is needed if the shape of your data is
not amenable to clean GCs. If that doesn't solve it, then we get far
funner problems with memory allocation.
More information about the erlang-questions
mailing list