I'm trying to setup postgres triggers in phoenix.
The docs state
In order to use it, first you need to start the notification process. In your supervision tree:
{Postgrex.Notifications, name: MyApp.Notifications}
So here's my implementation:
application.ex
defmodule Foo.Application do
...
def start do
children = [Foo.Repo, {Postgrex.Notifications, Name: Foo.Notifier}]
opts = [strategy: :one_for_one, name: Foo.Supervisor]
Supervisor.start_link(children, ops)
end
end
notifier.ex
defmodule Foo.Notifier do
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]}
}
end
def start_link(opts \\ []),
do: GenServer.start_link(__MODULE__, opts)
def init(opts) do
# setup postgres listeners
end
end
I get an error message saying
The module Postgrex.Notifications was given as a child to a supervisor but it does not implement child_spec/1.
If you own the given module, please define a child_spec/1 function that receives an argument and returns a child specification as a map.
However, if you don't own the given module and it doesn't implement child_spec/1, instead of passing the module name directly as a supervisor child, you will have to pass a child specification as a map
So I followed the example in the error
%{
id: Postgrex.Notifications,
start: {Postgrex.Notifications, :start_link, [arg1, arg2]}
}
my implementation:
children = [
Foo.Repo,
%{
id: Postgrex.Notifications,
start: {Postgrex.Notifications, :start_link, opts}
}
]
Supervisor.start_link(children, opts)
But now I get the error
** (Mix) Could not start application survey: exited in: Foo.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function Supervisor.start_link/1 is undefined or private
I found this tutorial
Instead of passing a tuple to the supervisor tree just pass your module and call start_link
manually
application.ex
children = [Foo.Repo, Foo.Notifier]
notifier.ex
@impl true
def init(opts) do
with {:ok, _pid, _ref} <- Repo.listen("some_channel_name") do
{:ok, opts}
else
error -> {:stop, error}
end
end
repo.ex
defmodule Foo.Repo do
def listen(channel) do
with {:ok, pid} <- Postgrex.Notifications.start_link(__MODULE__.config()),
{:ok, ref} <- Postgrex.Notifications.listen(pid, channel) do
{:ok, pid, ref}
end
end