boss revs
boss revs

Reputation: 351

How do i make a process state always on for elixir?

I have a simple program that when given a tupple message containing {pid,integer} will send a message back to the processor with its PID and the interger+1. The problem is that I need this program to be left active so i can send it multiple messages, and then when i flush() it, will send back its mailbox all at once. It only works 1 message at a time. I tried a recursion but it doesn't work. Here is what I have.

defmodule Spawner do
  def start() do

    spawn(fn ->
      receive do
        {pid,y} -> send(pid,y+1)
        Spawner.start()
      end
    end)

  end
end

Then on the terminal i would do:

> x = Spawner.start()
> send x, {self(),3}
> send x, {self(),5}
> flush()
#⇒ output: {PID,4}

I need the output to be {PID,4} and {PID,6}.

Thank you for your time.

Upvotes: 1

Views: 31

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Think about send as about ping-pong game. The rule is: one send ⇒ one consume. Exactly as in ping-pong one can not expect the proper behaviour from the opposite side, serving ten balls at once.

To accomplish what you want you are going to have a GenServer that collects all the received messages (instead of immediately answering to each of them.)

Also it would provide, say, get_all call, that would retrieve all the collected messages from it’s state and respond with the {int, list} tuple:

{PID, [msg1, msg2, ..., msgN]}

The implementation of that won’t fit the margins here, but since you have your question tagged with , GenServer tutorial would be a good start. Then you might want to read about Agent to hold the state.


Other way round (I do not recommend it) would be flush() the consumer recursively with a timeout. The empty queue would trigger a timeout. But, again, it’s not how it’s supposed to be done, because you probably want all the already sent messages to be collected somehow on the other side.

Upvotes: 2

Related Questions