简体   繁体   English

从另一个模块使用GenServer

[英]Using a GenServer from another module

I have a simple GenServer and here it is: 我有一个简单的GenServer,这里是:

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

I want to use this GenServer in this module: 我想在此模块中使用此GenServer:

MODULE: 模块:

  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

As pointed out in that code example I want to push some state during a loop on the GenServer and after I want to pop the state on the changeset below. 如该代码示例中所指出的,我想在GenServer上的循环过程中以及在下面的变更集上弹出状态后推送一些状态。

My main question is how do I initialize the genserver in the other module and is this a best practice? 我的主要问题是如何在其他模块中初始化genserver,这是最佳实践吗?

You will not want to initialize the GenServer in another module. 您将不想在另一个模块中初始化GenServer。 You will want to add it to your supervision tree. 您将需要将其添加到您的监督树中。

You may also want to consider adding "API" functions to your GenServer module so that the users of it do not need to know that it is a GenServer. 您可能还需要考虑将“ API”功能添加到GenServer模块,以便其用户不需要知道它是GenServer。 Something like 就像是

# 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

Then you can just call it like normal functions where you need it. 然后,您可以像需要的常规功能一样调用它。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM