Reputation: 351
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
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 elixir, 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