Правильный способ подписки на Phoenix PubSub с Genserver - PullRequest
1 голос
/ 06 мая 2020

Я пытался создать экземпляр процесса genserver, который будет подписываться на PubSub во фреймворке Phoenix, это мои файлы и ошибки:

config.ex:

config :excalibur, Excalibur.Endpoint,
  pubsub: [
    adapter: Phoenix.PubSub.PG2,
    name: Excalibur.PubSub
  ]

Модуль с использованием genserver:

defmodule RulesEngine.Router do
  import RulesEngine.Evaluator
  use GenServer
  alias Excalibur.PubSub

  def start_link(_) do
    GenServer.start_link(__MODULE__, name: __MODULE__)
  end

  def init(_) do
    {:ok, {Phoenix.PubSub.subscribe(PubSub, :evaluator)}}
    IO.puts("subscribed")
  end

  # Callbacks

  def handle_info(%{}) do
    IO.puts("received")
  end

  def handle_call({:get, key}, _from, state) do
    {:reply, Map.fetch!(state, key), state}
  end
end

и когда я делаю смесь iex -S, возникает эта ошибка:

** (Mix) Could not start application excalibur: Excalibur.Application.start(:normal, []) returned an error: shutdown: failed to start child: RulesEngine.Router
    ** (EXIT) an exception was raised:
        ** (FunctionClauseError) no function clause matching in Phoenix.PubSub.subscribe/2
            (phoenix_pubsub 1.1.2) lib/phoenix/pubsub.ex:151: Phoenix.PubSub.subscribe(Excalibur.PubSub, :evaluator)
            (excalibur 0.1.0) lib/rules_engine/router.ex:11: RulesEngine.Router.init/1
            (stdlib 3.12.1) gen_server.erl:374: :gen_server.init_it/2
            (stdlib 3.12.1) gen_server.erl:342: :gen_server.init_it/6
            (stdlib 3.12.1) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

Итак, это правильный способ развернуть Genserver, который будет подписываться на PubSub topi c?

1 Ответ

2 голосов
/ 06 мая 2020

Согласно документации, Phoenix.PubSub.subscribe/3 имеет следующий spe c:

@spec subscribe(t(), topic(), keyword()) :: :ok | {:error, term()}

где @type topic :: binary(). Тем не менее, ваш init/1 должен выглядеть как

def init(_) do
  {:ok, {Phoenix.PubSub.subscribe(PubSub, "evaluator")}}
  |> IO.inspect(label: "subscribed")
end

Обратите внимание, что я также изменил IO.puts/1 на IO.inspect/2, чтобы сохранить возвращаемое значение.

...