Book "Programming Phoenix 1.4" => failed to start child: RumblWeb.Presence

What this topic has made me realize is that, the ordering of the child applications in your application.ex matters. The whole time my children list was like this:

    children = [
      # Start the Telemetry supervisor
      # RumblWeb.Telemetry,
      # Start the Endpoint (http/https)
      RumblWeb.Endpoint,
      RumblWeb.Presence,
      {Phoenix.PubSub, name: RumblWeb.PubSub},
      # Start a worker by calling: RumblWeb.Worker.start_link(arg)
      # {RumblWeb.Worker, arg}
    ]

So if you’ve got Presence before PubSub you get the error below when you try mix phx.server:

╰─$ mix phx.server
==> rumbl_web
Compiling 1 file (.ex)
[info] Running RumblWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:4000 (http)
[info] Access RumblWeb.Endpoint at http://localhost:4000
[info] Application rumbl_web exited: RumblWeb.Application.start(:normal, []) returned an error: shutdown: failed to start child: RumblWeb.Presence
    ** (EXIT) shutdown: failed to start child: Phoenix.Presence.Tracker
        ** (EXIT) shutdown: failed to start child: RumblWeb.Presence_shard0
            ** (EXIT) an exception was raised:
                ** (ArgumentError) unknown registry: RumblWeb.PubSub
                    (elixir 1.11.4) lib/registry.ex:999: Registry.meta/2
                    (phoenix_pubsub 2.0.0) lib/phoenix/pubsub.ex:262: Phoenix.PubSub.node_name/1
                    (phoenix_pubsub 2.0.0) lib/phoenix/tracker/shard.ex:122: Phoenix.Tracker.Shard.init/1
                    (stdlib 3.14.2) gen_server.erl:417: :gen_server.init_it/2
                    (stdlib 3.14.2) gen_server.erl:385: :gen_server.init_it/6
                    (stdlib 3.14.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
** (Mix) Could not start application rumbl_web: RumblWeb.Application.start(:normal, []) returned an error: shutdown: failed to start child: RumblWeb.Presence
    ** (EXIT) shutdown: failed to start child: Phoenix.Presence.Tracker
        ** (EXIT) shutdown: failed to start child: RumblWeb.Presence_shard0
            ** (EXIT) an exception was raised:
                ** (ArgumentError) unknown registry: RumblWeb.PubSub
                    (elixir 1.11.4) lib/registry.ex:999: Registry.meta/2
                    (phoenix_pubsub 2.0.0) lib/phoenix/pubsub.ex:262: Phoenix.PubSub.node_name/1
                    (phoenix_pubsub 2.0.0) lib/phoenix/tracker/shard.ex:122: Phoenix.Tracker.Shard.init/1
                    (stdlib 3.14.2) gen_server.erl:417: :gen_server.init_it/2
                    (stdlib 3.14.2) gen_server.erl:385: :gen_server.init_it/6
                    (stdlib 3.14.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

So that’s probably because the applications are started in the order they are defined in the children list (please correct me if I am wrong as I am a newbie in Elixir/Phoenix).

Hence if you just swap the places of PubSub and Presence like below everything will be fine.

    children = [
      # Start the Telemetry supervisor
      # RumblWeb.Telemetry,
      # Start the Endpoint (http/https)
      RumblWeb.Endpoint,
      {Phoenix.PubSub, name: RumblWeb.PubSub},
      RumblWeb.Presence,
      # Start a worker by calling: RumblWeb.Worker.start_link(arg)
      # {RumblWeb.Worker, arg}
    ]

This information might be helpful for newcomers like me.