I’m working my way through “Phoenix in Action 1.4” for the second time. The instructions have you create an umbrella app with two apps: auction
and auction_web
, and following the instructions I created the auction_web
app with --no-ecto
. Unfortunately, --no-ecto
seems to be the root cause of continuing PubSub warnings/errors. I was successful squelching the PubSub warnings/errors for a few days while I was working on getting the auction_web
app to display a list of items on a web page, but then I moved inside the auction
app to create a Postgres database, and when I tried to execute iex -S mix
, then PubSub, like a Phoenix, rose from the ashes to bite me again:
...phoenix_apps/second_auction/auction_umbrella $ iex -S mix
...
...
...
> 14:25:30.946 [notice] Application eex exited: :stopped
> ** (Mix) Could not start application auction: Auction.Application.start(:normal, []) returned an error: shutdown: failed to start child: Phoenix.PubSub.Supervisor
> ** (EXIT) shutdown: failed to start child: Phoenix.PubSub.PG2
> ** (EXIT) shutdown: failed to start child: Auction.PubSub.Adapter
> ** (EXIT) exited in: :gen_server.call(Phoenix.PubSub, {:join_local, Auction.PubSub.Adapter, #PID<0.4916.0>}, :infinity)
> ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
Am I in the wrong directory? If I change into apps/auction/
and try again, I get:
auction_umbrella/apps/auction$ iex -S mix
Generated auction app
15:13:27.742 [notice] Application auction exited: exited in: Auction.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (ArgumentError) The module Phoenix.PubSub was given as a child to a supervisor but it does not exist
(elixir 1.16.0-rc.1) lib/supervisor.ex:797: Supervisor.init_child/1
(elixir 1.16.0-rc.1) lib/enum.ex:1700: Enum."-map/2-lists^map/1-1-"/2
(elixir 1.16.0-rc.1) lib/supervisor.ex:783: Supervisor.init/2
(elixir 1.16.0-rc.1) lib/supervisor.ex:707: Supervisor.start_link/2
(kernel 9.1) application_master.erl:293: :application_master.start_it_old/4
15:13:27.747 [notice] Application ecto_sql exited: :stopped
15:13:27.747 [notice] Application postgrex exited: :stopped
15:13:27.747 [notice] Application db_connection exited: :stopped
15:13:27.747 [notice] Application ecto exited: :stopped
15:13:27.748 [notice] Application decimal exited: :stopped
15:13:27.748 [notice] Application telemetry exited: :stopped
15:13:27.748 [notice] Application eex exited: :stopped
** (Mix) Could not start application auction: exited in: Auction.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (ArgumentError) The module Phoenix.PubSub was given as a child to a supervisor but it does not exist
(elixir 1.16.0-rc.1) lib/supervisor.ex:797: Supervisor.init_child/1
(elixir 1.16.0-rc.1) lib/enum.ex:1700: Enum."-map/2-lists^map/1-1-"/2
(elixir 1.16.0-rc.1) lib/supervisor.ex:783: Supervisor.init/2
(elixir 1.16.0-rc.1) lib/supervisor.ex:707: Supervisor.start_link/2
(kernel 9.1) application_master.erl:293: :application_master.start_it_old/4
And, if I switch into apps/auction_web/
I get:
auction_umbrella/apps/auction_web$ iex -S mix
Erlang/OTP 26 [erts-14.1.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
Interactive Elixir (1.16.0-rc.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
I’m using:
Phoenix 1.7.10
Erlang/OTP 26.1.2
Elixir 1.16.0-rc.1-otp-26
Here are all the places where the name PubSub
occurs in my umbrella app:
- apps/auction/lib/auction/application.ex:
defmodule Auction.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: Auction.Worker.start_link(arg)
# {Auction.Worker, arg}
{Phoenix.PubSub, name: Auction.PubSub},
{Auction.Repo, []}
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Auction.Supervisor]
Supervisor.start_link(children, opts)
end
end
- apps/auction_web/lib/auction_web/application.ex:
defmodule AuctionWeb.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
@impl true
def start(_type, _args) do
children = [
{Phoenix.PubSub, name: AuctionWeb.PubSub},
AuctionWeb.Telemetry,
# Start a worker by calling: AuctionWeb.Worker.start_link(arg)
# {AuctionWeb.Worker, arg},
# Start to serve requests, typically the last entry
AuctionWeb.Endpoint
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: AuctionWeb.Supervisor]
Supervisor.start_link(children, opts)
end
# Tell Phoenix to update the endpoint configuration
# whenever the application is updated.
@impl true
def config_change(changed, _new, removed) do
AuctionWeb.Endpoint.config_change(changed, removed)
:ok
end
end
- auction_umbrella/config/config.exs:
# This file is responsible for configuring your umbrella
# and **all applications** and their dependencies with the
# help of the Config module.
#
# Note that all applications in your umbrella share the
# same configuration and dependencies, which is why they
# all use the same configuration file. If you want different
# configurations or dependencies per app, it is best to
# move said applications out of the umbrella.
import Config
# Stuff I added:
config :auction, ecto_repos: [Auction.Repo]
config :auction, Auction.Repo,
database: "auction",
username: "7stud",
password: "",
hostname: "localhost",
port: "5432"
##############################
config :auction_web,
generators: [context_app: false]
# Configures the endpoint
config :auction_web, AuctionWeb.Endpoint,
url: [host: "localhost"],
adapter: Phoenix.Endpoint.Cowboy2Adapter,
render_errors: [
formats: [html: AuctionWeb.ErrorHTML, json: AuctionWeb.ErrorJSON],
layout: false
],
pubsub_server: AuctionWeb.PubSub,
live_view: [signing_salt: "cOmLEVHn"]
# Configure esbuild (the version is required)
config :esbuild,
version: "0.17.11",
default: [
args:
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../apps/auction_web/assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
]
# Configure tailwind (the version is required)
config :tailwind,
version: "3.3.2",
default: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../apps/auction_web/assets", __DIR__)
]
# Sample configuration:
#
# config :logger, :console,
# level: :info,
# format: "$date $time [$level] $metadata$message\n",
# metadata: [:user_id]
#
import Config
# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"