Реализация GenServer обработчика событий, не обрабатывающего приведения

Я пытаюсь использовать GenServer в качестве обработчика событий для EventBus в моем приложении Phoenix, но по какой-то причине я не могу понять, почему функция приведения дескриптора не вызывается. Я проверил, что процесс жив с :observer.start().

Есть ли что-то, чего мне не хватает, чтобы GenServer правильно обрабатывал вызов приведения?

По сути, функция процесса должна обрабатывать входящее событие и приводить его к GenServer, где GenServer будет обрабатывать приведение и выполнять логику предметной области для этого события.

----Генеральный серверный модуль----

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

---- Модуль приложения -----

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

person john    schedule 26.06.2019    source источник


Ответы (1)


В документации по GenServer.cast/2 указано, что первый параметр при вызове GenServer.cast/2 должен иметь значение тип server():

любые значения, описанные в разделе «Регистрация имени» документацию к этому модулю.

В вашем коде вы запускаете ссылку без имени:

GenServer.start_link(__MODULE__, [], opts)

но затем вы приводите к имени GenServer:

#              ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
GenServer.cast(__MODULE__, {topic_id, event_id})

Самый простой способ это исправить, запустить сервер с именем:

GenServer.start_link(__MODULE__, [], name: __MODULE__)
person Aleksei Matiushkin    schedule 26.06.2019