title: Supervise a gen_tcp client/server
body: <p>I'm using Phoenix framework and trying to configure a process which will connect to another server which gives me some feeds. I'm using Erlang's <code>gen_tcp</code> to do that. I want to send those feeds to clients connected with Channels later (not really that important).</p>
  
  <p>I want it to be supervised, so if there is no connection to the remote resources the application won't break but wait for the connection to restore. If there is any error I would like it to be restarted by supervisor.</p>
  
  <p>This is what i tried:</p>
  
  <pre><code>defmodule HelloPhoenix.TestServer do
    use GenServer
  
    def start_link() do
      GenServer.start_link(__MODULE__, [])
    end
  
    def init(_) do 
      pid = spawn run
      {:ok, pid}
    end
  
    def run do
      socket = _connect()
      _loop(socket)
    end
  
    defp _loop(socket) do
  
      _recv(socket) |&gt;
      _handle_message(socket) |&gt;
      _broadcast
  
      _loop socket
    end
  
    defp _connect do
      opts = [:binary, packet: :line, active: false, reuseaddr: true, keepalive: true]
      {:ok, socket} = :gen_tcp.connect('10.10.10.10', 1000, opts)
      socket
    end
  
    defp _recv(socket) do
      case :gen_tcp.recv(socket, 0) do
        {:ok, m} -&gt; m
        {:error, _} -&gt; raise :disconnected
      end
    end
  
    defp _handle_message(message, _socket) do
      # parse message and stuff like that
      String.strip message
    end
  
    defp _broadcast(parsed_message) do
      HelloPhoenix.Endpoint.broadcast("room:lobby", "receive", parsed_message)
    end
  
  end
  </code></pre>
  
  <p>I also added worker to Application supervisor. This works, but when I restart connection I get errors like that (whole application crashes...):</p>
  
  <pre><code>=INFO REPORT==== 14-Mar-2016::23:53:54 ===
      application: logger
      exited: stopped
      type: temporary
  ** (Mix) Could not start application hello_phoenix: HelloPhoenix.start(:normal, []) returned an error: shutdown: failed to start child: HelloPhoenix.TestServer
      ** (EXIT) an exception was raised:
          ** (RuntimeError) :disconnected
              (hello_phoenix) lib/hello_phoenix/test_server.ex:83: HelloPhoenix.TestServer._handle_message/2
              (hello_phoenix) lib/hello_phoenix/test_server.ex:46: HelloPhoenix.TestServer._loop/1
              (hello_phoenix) lib/hello_phoenix/test_server.ex:43: HelloPhoenix.TestServer._loop/1
              (hello_phoenix) lib/hello_phoenix/test_server.ex:34: HelloPhoenix.TestServer._run/0
              (hello_phoenix) lib/hello_phoenix/test_server.ex:12: HelloPhoenix.TestServer.init/1
              (stdlib) gen_server.erl:328: :gen_server.init_it/6
              (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
  </code></pre>
  
  <p>How should I approach this so it's never gonna crash / will wait for reconnect?</p>