deerob4

deerob4

Moving from GenEvent to GenStage

I’m writing a quiz system using Elixir. Every time a user chooses an answer to a question, an %AnswerPacket{} struct is created, containing information on the answer. This packet is then processed by two GenServers, ScoreServer and AnswerServer, both of which have an update/2 function, taking the server pid and the packet.

Currently, I’m implementing this using GenEvent. There’s a third process, PacketHandler, that has a :push_packet event which forwards the packet to ScoreServer and AnswerServer, as below:

def handle_event({:push_packet, packet}, %{scores: scores, answers: answers} = pids)  do
  ScoreServer.update(scores, packet)
  AnswerServer.update(answers, packet)
  {:ok, pids}
end

This works pretty well, but I’m interested in how it could be reimplemented using GenStage. Am I right in thinking that PacketHandler would be the producer, and ScoreServer and AnswerServer consumers? If so, how would PacketHandler work? Currently the event is triggered by a function call, but the examples I’ve seen of GenStage seem more like a stream. And how does it fit in with the concept of demand, if its dependent on the user choosing an answer?

I’m a bit confused, so any help would be appreciated xD

Most Liked

josevalim

josevalim

Creator of Elixir

Correct. To add to your reply, the PacketHandler likely wants to use the broadcast dispatcher, to ensure every event is broadcast to all consumers.

The GenStage documentation contains two examples of how a PacketHandler could be implemented (see the Broadcaster examples). There is another example in the source code.

wfgilman

wfgilman

Based on my understanding, PacketHandler would be a producer and ScoreServer and AnswerServer would be consumers, as you expected. When they are implemented, they are simply up and running, waiting for information to process. To get things started, when someone answered a question, you would send a message to PacketHandler letting it know there is information to process. Add something like this to the code that creates the %AnswerPacket{}.

send PacketHandler, :new_answer

and something like this to PacketHandler

handle_info(:new_answer, state) do
  ...
 {:noreply, events, state}
end

In the init function of PacketHandler, you can specify the :dispatcher option which allows you to tailor how PacketHandler communicates with ScoreServer and AnswerServer.

Watching this talk a couple of times helped me wrap my head around GenStage.

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement