Reputation: 8461
I have a simple GenServer and here it is:
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:
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.
My main question is how do I initialize the genserver in the other module and is this a best practice?
Upvotes: 0
Views: 247
Reputation: 10061
You will not want to initialize the GenServer in another module. 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. 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()
...
Upvotes: 4