sezaru

sezaru

Fastest way to a GenServer communicate with all childrens of some supervisor?

Hello,

A part of my application currently have a supervisor hierarchy that looks something like this:

As you can see, I have a Manager Genserver and a Childs Supervisor that will contain a lot of children’s (this is a normal supervisor for now, but maybe in the future I would want to start the children on demand, so that can be changed to a Dynamic Supervisor in the future I guess).

My question is regarding the Manager Genserver communication with the children’s. Basically Manager Genserver needs to send broadcast messages to all the children’s, this can happen very frequently (like multiple times a second), so I have a performance concern.

So, what kind of communication strategy should I use in this case? I’m kinda new with OTP, so I’m not 100% sure and are contemplating the following solutions:

  1. Create a function inside Childs Supervisor that will iterate and do a GenServer.call to all it’s children. Not sure if this is efficient or will bottleneck all the communication if one children blocks the call for some reason;

  2. Send a message from each Child to the Manager GenServer with it’s PID, store it in a list and send GenServer.call iterating through it;

  3. Use a PubSub system like Phoenix.PubSub. This seems like a good solution, but as far as I know the Phoenix.PubSub is global and used more for a distributed case. I’m not sure if using it would be over-engineering and maybe be a bottleneck;

  4. Use the Registry. this seems like another good solution too but I only saw examples of global (but local to the beam node) examples of Registry, in my case I only want to handle communication from Manager Genserver to all the Childs, is it possible to create maybe a local Registry for Parent Supervisor?

Any help would be much appreciated.

Thanks a lot!

Most Liked

kokolegorille

kokolegorille

Supervisor has the which children function (and more…)

https://hexdocs.pm/elixir/Supervisor.html#which_children/1

You should try to benchmark if sending message to that list of children is within your refresh frequency.

lud

lud

Your 1) timeouts because you implemented it inside a handle_call and call it from another process. But this problem is out of scope. You could add a :infinity timeout.

You could call all children concurrently:

    reply = state.childs
    |> Map.values()
    |> Enum.map(fn pid -> Task.async(fn -> GenServer.call(pid, {:received_msg, "hello"}) end) end)
    |> Enum.map(&Task.await/1)

Edit: but this is a poor man’s implementation of GenServer.multi_call.

Or use Task.async_stream to limit the number of concurrent calls.

Calling your children with GenServer.call provides another guarantee : all calls will be made before you start to call your children again. The other solutions do not give this guarantee. But you may not care about it.

Where Next?

Popular in Questions Top

itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single 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
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
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
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
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
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
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement