[erlang-questions] Writing gen_servers with TCP listeners

Eric Maland <>
Sun May 11 22:25:31 CEST 2008


Hello,

I am having some trouble writing a gen_server that is a tcp listener  
that works outside the shell.

My goal has been to write a gen_server that starts listening on a  
socket and manages a connection pool of accept()-ors.  This seems like  
a pretty standard behaviour and is very easy to implement, but every  
implementation I've produced runs perfectly in the shell but not in an  
erl instance without a shell.

This sort of problem seems to be referenced in a previous thread (http://www.erlang.org/pipermail/erlang-questions/2008-January/032400.html 
  ), but I have found 0 examples of how to apply the information there  
to a gen_server - clearly the server needs to live forever, but how do  
you get a gen_server to hang around?  Is it acceptable to implement a  
handle_call() that just does a receive after infinity -> foo end ???   
Who would call that?  I have tried that, and it seemed like after 10  
or so requests the server died (presumably on some timeout from the  
supervisor insantiating it??).

I found a great example of a gen_server tcp listener at http://www.duomark.com/erlang/tutorials/proxy.html 
   but this also exhibits the same problem outside the shell - it  
serves one request and then the socket is closed.

Does anyone have or know of a great tcp listener example that works  
outside the shell (eg started with: 'erl -boot start_sasl -s mymodule  
start'), or another interesting way to resolve this, specifically when  
writing  gen_server?

Here are some models I have gone through, all of which work in the  
shell but not outside the shell:

gen_server:init listen()'s ->
   spawn()'s a connection pool ->
     each pool process accept()'s and spawns another pool process

In the shell: works fine
Outside the shell: 2nd and subsequent accept() fails

gen_server:init listen()'s ->
   gen_server:init calls gen_server:cast(accept_loop) ->
     accept_loop loops forever, spawning handlers on each request (and  
gen_tcp:controlling_process the associated connections over to the  
processes)

In the shell: works fine
Outside the shell: 2nd and subsequent accept() fails

These all work great in the shell but serve 1-2 requests (depending on  
your platform) outside the shell before the socket closes.

Any advice on how to properly get the owner of the listening socket to  
stick around in a gen_server would be appreciated.

Thanks!
Eric


References:
1. http://www.erlang.org/pipermail/erlang-questions/2008-January/032400.html
2. http://www.duomark.com/erlang/tutorials/proxy.html



More information about the erlang-questions mailing list