[erlang-questions] gen_server etc: blocking init, blocking cast

Oliver Korpilla Oliver.Korpilla@REDACTED
Fri Apr 15 00:23:36 CEST 2016


I was trying to write a gen_server for handling a TCP connection. So, there would be an instance of gen_server for each open connection. (Each instance would have a copy of the socket returned by gen_tcp:listen to start accepting a connection from.)

One thing I noticed is that gen_tcp does not seem to play very well with OTP's assumptions since accept is a blocking call, at least I understood it (and the principles) that way.

So, on the net I saw examples dealing with accept in init/1. So, this will delay init/1 from finishing until there is either a timeout or there is a connection. I read somewhere else that it is a good practice to keep init from blocking...

I saw an example (I think it was in "Learn You Some Erlang Good") that delayed the accept call by calling gen_server:cast and sending your own mailbox a trigger that was immediately followed by the blocking accept call. While this certainly was keeping init short, I wonder what was exactly gained here?

Both init and handle_cast get executed in the new process started by gen_server:start_link. If either of them blocks, the process cannot react to anything else, right? So, how would a cast blocking the server be better than init? The process is still not responsive to events.

I might be missing something here, but this seems to be the case with all blocking calls - they do not seem to play so well with OTP principles. I mean, gen_tcp could actually also allow the socket returned by gen_tcp:listen to act like an active socket and generate {tcp_accept, ...} or something. Did I miss something here?

Or is there an entirely different pattern for writing workers with blocking calls?

Thanks for reading,

More information about the erlang-questions mailing list