Starting multiple apps

I currently have 3 apps in an umbrella project, 1 Phoenix and 2 gen_server.

  • WebDisplay
  • AppA
  • AppB

For the purposes of this test, only WebDisplay connects to the other apps, but in the future there will be others that ned to communicate with them.

Im struggling to figure out a way to supervise all of the apps and make sure that they all stay running. I had 2 ideas;

Use the Phoenix app (WebDisplay) to supervise the other apps, but that would mean that if the WebDisplay app restarted, then the other apps would be restarted as well - which is not ideal for the future.

Create a new app (Main) that would supervise all the other apps, so they could be restarted independently of each other. This half works, but if I try and run iex -S mix phoenix.server from the Main app it errors with:

    ** (Mix) Could not start application main: Main.start(:normal, []) returned an error: shutdown: failed to start child: WebDisplay.Endpoint
    ** (EXIT) shutdown: failed to start child: Phoenix.Endpoint.Server
        ** (EXIT) shutdown: failed to start child: {:ranch_listener_sup, WebDisplay.Endpoint.HTTP}
            ** (EXIT) exited in: :gen_server.call(:ranch_server, {:set_new_listener_opts, WebDisplay.Endpoint.HTTP, 16384, [env: [dispatch: [{:_, [], [{["phoenix", "live_reload", "socket", "longpoll"], [], Plug.Adapters.Cowboy.Handler, {Phoenix.Transports.LongPoll, {WebDisplay.Endpoint, Phoenix.LiveReloader.Socket, :longpoll}}}, {["phoenix", "live_reload", "socket", "websocket"], [], Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, {WebDisplay.Endpoint, Phoenix.LiveReloader.Socket, :websocket}}}, {["socket", "websocket"], [], Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, {WebDisplay.Endpoint, WebDisplay.UserSocket, :websocket}}}, {:_, [], Plug.Adapters.Cowboy.Handler, {WebDisplay.Endpoint, []}}]}]]]})
                ** (EXIT) no process

I feel like the second approach is better, but not sure how to go about it properly.
My main.ex looks like:

defmodule Main do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false


    children = [
      supervisor(App1.Supervisor, []),
      supervisor(App2.Supervisor, []),
      supervisor(WebDisplay.Endpoint, [])
    ]

    opts = [strategy: :one_for_one, name: Main.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Does anyone have any suggestions on the best way forward?

Applications do not need to supervise each other. Each application needs its own top level supervisor. If WebDisplay depends on appa and appb then they need to be added to the mix.exs applications list. That’s all you need :slight_smile:

Think about it, you don’t supervise :httpoison or :ex_aws or any of your other dependencies. Umbrella applications have the same relationship to each other.

4 Likes

Gotcha!

I was totally over thinking the whole thing! Thanks!