I've been following the (brilliant!) 'Mix and OTP' tutorial from the official Getting Started guide, and I've just got to the end of the 'Docs, tests & pipelines' page (
http://elixir-lang.org/getting-started/mix-otp/docs-tests-and-pipelines.html).
Playing around with the server that's been implemented at this stage of the tutorial via telnet, I noticed that if I disconnected my telnet client, my laptop's CPU usage skyrocketed. After dropping a few calls to IO.puts lines into my server code, I realised that after the data socket is closed, the server continues trying to read from it, receiving "{:error, :enotconn}" each time and continuing like this forever.
I'm wondering now if I missed something in the tutorial - though I'm reasonably confident I copied all the code correctly - or if this is just a scenario that's deliberately overlooked for brevity. In the latter case, maybe it should be mentioned that 'real' code should deal with the case of the socket being closed?
I eventually worked around the issue by modifying my 'serve' function to look like this:
defp serve(socket) do
import Pipe
msg =
pipe_matching x, {:ok, x},
read_line(socket)
|> KVServer.Command.parse()
|> KVServer.Command.run()
case msg do
{:error, :closed} -> :ok
{:error, :enotconn} -> :ok
_ -> serve_response(socket, msg)
end
end
defp serve_response(socket, msg) do
write_line(socket, msg)
serve(socket)
end
Though I've no idea if this is idiomatic or even remotely the right way to handle this situation!