[erlang-questions] Building a Non-blocking TCP server using OTP principles
Thu Sep 20 23:53:59 CEST 2007
On Thu, Sep 20, 2007 at 04:06:46PM -0400, Dave Rafkind wrote:
> Just to bring this back up again, I looked at ejabberd_listener.erl and as
> far as I can tell,
> the strategy is to have a "master acceptor" supervisor that babysits some
> processes doing gen_tcp:listen() and gen_tcp:accept(), in a "normal"
> blocking manner.
> When each worker's gen_tcp:accept() returns with a client socket, the socket
> is then passed along to a separate "controller" process (supervised by
> something else) and the worker goes back to accepting.
> Does the fact that the worker processes are properly supervised and can be
> administrated through supervision make this an "officially safe" way to have
> a non-blocking tcp server?
The problem with doing a blocking gen_tcp:accept() is that it prevents
you from doing code reloading on that module. If you can do it in
a small gen_server that never changes, that's ok.
Personally, I prefer to have a gen_server that simply holds the
listen socket, and implement my socket handler has a gen_fsm that
starts in a listen state. It sends itself 'accept' state messages.
the listen(accept, ...) calls gen_tcp:accept() with a short timeout.
If it returns error,timeout, send accept to self. If it succeeds,
tell the supervisor to start another fsm in the listen state and
go into the initial connection state.
This avoids having to play startup games with calling
gen_tcp:controlling_process() and then allowing the connection to go
ahead, which I hate. And I find the gen_fsm paradigm more useful for
socket owners anyway.
More information about the erlang-questions