I am trying to use GenServer
as an event handler for EventBus
in my Phoenix application but for some reason I can't seem to figure out why the handle cast function isn't getting called. I checked that the process was alive with :observer.start()
.
Is there something I'm missing for the GenServer
to handle the cast call correctly?
Essentially the process function is supposed to handle an incoming event and cast it to the GenServer
where the GenServer
will handle the cast and perform domain logic on that event.
----Gen server module----
defmodule App.Notifications.EventHandler do
use GenServer
require Logger
def start_link(opts \\ []) do
{:ok, pid} = GenServer.start_link(__MODULE__, [], opts)
end
def init([]) do
{:ok, []}
end
def process({topic_id, event_id}) do
Logger.info("event notification process recieved!!") <---- THIS IS GETTING PRINTED!
GenServer.cast(__MODULE__, {topic_id, event_id})
end
def handle_cast({topic_id, event_id}, state) do
Logger.info("event notification data Recieved!!") <----- THIS IS NOT
# do stuff
{:noreply, state}
end
end
----App module-----
defmodule App.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
def start(_type, _args) do
EventBus.subscribe({App.Notifications.EventHandler, ["^event_notification_created$"]})
# List all child processes to be supervised
children = [
# Start the Ecto repository
App.Repo,
# Start the endpoint when the application starts
AppWeb.Endpoint,
# Starts a worker by calling: App.Worker.start_link(arg)
# {App.Worker, arg},,
App.Notifications.EventHandler <--- STARTING THE GEN SERVER HERE
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: App.Supervisor]
Supervisor.start_link(children, opts)
end
# Tell Phoenix to update the endpoint configuration
# whenever the application is updated.
def config_change(changed, _new, removed) do
App.Endpoint.config_change(changed, removed)
:ok
end
end
Documentation on GenServer.cast/2
states, that the first parameter in call to GenServer.cast/2
must be of a type server()
which is:
any of the values described in the “Name registration” section of the documentation for this module.
In your code you start the link unnamed:
GenServer.start_link(__MODULE__, [], opts)
but then you cast to the named GenServer
:
# ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
GenServer.cast(__MODULE__, {topic_id, event_id})
The easiest way to fix it, start the server named:
GenServer.start_link(__MODULE__, [], name: __MODULE__)