derek-zhou

derek-zhou

Is there any easy way to coalesce messages in the mailbox?

Right now I am using PubSub to send messages to a dedicated genServer, which will handle them in order. The handling of a message may take some time, and in the mean time a newer, but otherwise same message could come in. My message handing is idempotent so some amount of duplication is ok; However, it is still a waste of computation. Can I peek ahead in my mailbox during handle_info/2, and cancel all pending messages that match a certain pattern?

Marked As Solved

dominicletz

dominicletz

Creator of Elixir Desktop

I’ve done selective receive with after 0 a couple of times to batch messages. But you can also de-duplicate. e.g.

defmodule Dedup do
  def example_process() do
    Process.sleep(100)
    receive do
      message ->
        dedup(message)
        dosomething(message)
    end

    example_process()
  end

  def dedup(message) do
    receive do
      ^message ->
        dedup(message)
    after
      0 -> :ok
    end
  end

  defp dosomething(message) do
    IO.puts("Got #{inspect(message)}")
  end
end

You probably only need the dedup() method. The rest is just to run the example. Every number will be printed only once even though there are a total of 100 messages sent.

iex(1)> pid = spawn_link &Dedup.process/0
#PID<0.383.0>
iex(2)> for i <- 1..100, do: send(pid, div(i, 10))
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, ...]
Got 0
Got 1   
Got 2   
Got 3   
Got 4   
Got 5   
Got 6   
Got 7   
Got 8   
Got 9   
Got 10  
iex(3)> 

Also Liked

hauleth

hauleth

You can do selective receive, but that will take longer with growth of the message queue. Instead I would add some idempotency token to the message and use that to reject the messages that were already processed, so instead of rejecting messages that you have already computed during computing them, discard them as soon as these arrive.

Where Next?

Popular in Questions Top

freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
gazoon
I want to know absolute current module path. In python i could do that: os.path.abspath(__file__) Does elixir have anything similar?
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
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
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New

We're in Beta

About us Mission Statement