【问题标题】:Using a GenServer from another module使用来自另一个模块的 GenServer
【发布时间】:2018-10-15 00:26:10
【问题描述】:

我有一个简单的 GenServer,它是:

GenServer:

defmodule MyApp.ScoreTableQueue do
  use GenServer

  @impl true
  def init(stack) do
    {:ok, stack}
  end

  @impl true
  def handle_call(:pop, _from, state) do
    {:reply, state, []}
  end

  @impl true
  def handle_cast({:push, item}, state) do
    {:noreply, [item | state]}
  end
end

我想在这个模块中使用这个 GenServer:

模块:

  defp order_score(question, season) do
    for team <- season.teams do
      state = score_table_map(question, team)

      # Push state on GenServer queue
    end

    create_score_table(question, season)
  end

  defp score_table_map(question, team) do
    p_score = Enum.find(team.prediction_scores, &(&1.question_id == question.id))
    %{team_score: p_score.score, team_id: p_score.team_id}
  end

  defp create_score_table(question, season) do
    changeset = ScoreTable.changeset(%ScoreTable{
      question_id: question.id,
      season_id: season.id,
      table_details: %{
        information: # Pop state of genserver
      }
    })

    Repo.insert(changeset)
  end

正如该代码示例中所指出的,我想在 GenServer 上的循环期间推送一些状态,并且在我想在下面的变更集上弹出状态之后。

我的主要问题是如何在另一个模块中初始化 genserver,这是最佳实践吗?

【问题讨论】:

    标签: elixir


    【解决方案1】:

    您不希望在另一个模块中初始化 GenServer。您需要将其添加到您的监督树中。

    您可能还想考虑将“API”函数添加到您的 GenServer 模块,以便它的用户不需要知道它是一个 GenServer。类似的东西

    # This assumes you have named your GenServer the same as the module name
    def push(item) do
      GenServer.call(__MODULE__, {:push, item})
    end
    
    def pop() do
      GenServer.call(__MODULE__, :pop)
    end
    

    然后你可以在你需要的地方像普通函数一样调用它。

    MyApp.ScoreTableQueue.push(:foo)
    stack = MyApp.ScoreTableQueue.pop()
    ...
    

    【讨论】:

      猜你喜欢
      • 2017-04-22
      • 2019-05-08
      • 2017-01-28
      • 2019-05-13
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多