Phillipp
Process communication in a dynamic supervision setup
Hey,
let’s say I have a DynamicSupervisor and I want to start children on it. The children itself consist of a Supervisor with a few children on it, which act like one unit under the DynamicSupervisor.
Something like this:
DynamicSupervisor
-- Supervisor
------ Main
------ Worker_1
------ Worker_2
------ Something_else
-- Supervisor
------ Main
------ Worker_1
------ Worker_2
------ Something_else
...
So, our “unit” has 4 GenServers in the example above. What would be the best way to let them easily communicate with each other? I need to find out the pids of the related processes. Has someone done something like this before and can recommend a good way?
A simple usecase here is that Main tells the 3 other servers what to do and they report back to Main.
Marked As Solved
Phillipp
So, I played around a bit and created an example add.
I used a single Registry which seems to work fine. Code can be found here:
For now, I just added the mechanism to start a new unit which then starts a service and two worker processes. Gonna add unit listing/deletion/state retrieval too. In the mean time, feel free to look over the code and suggest things that could be improved (concept wise).
Here is an example console output:
iex(82)> MyApp.add_unit "Unit 1"
{:ok, #PID<0.1344.0>}
iex(83)> Unit 1/:worker_two got work to do
Unit 1: Message from :worker_two: I don't really wanna do the work today!
Unit 1/:worker_two got work to do
Unit 1: Message from :worker_two: I don't really wanna do the work today!
Unit 1/:worker_one got work to do
Unit 1: Message from :worker_one: I don't really wanna do the work today!
Unit 1/:worker_one got work to do
Unit 1: Message from :worker_one: I don't really wanna do the work today!
nil
iex(84)> MyApp.add_unit "Unit 2"
{:ok, #PID<0.1351.0>}
iex(85)> Unit 1/:worker_one got work to do
Unit 1: Message from :worker_one: I don't really wanna do the work today!
Unit 2/:worker_one got work to do
Unit 2: Message from :worker_one: I don't really wanna do the work today!
Unit 1/:worker_one got work to do
Unit 1: Message from :worker_one: I don't really wanna do the work today!
Unit 2/:worker_two got work to do
Unit 2: Message from :worker_two: I don't really wanna do the work today!
Also Liked
david_ex
It sounds like you’re looking for the service/worker pattern: https://zxq9.com/archives/1311
Coincidentally, I’ve written a series of blog posts that use it in practice: http://davidsulc.com/blog/2018/07/09/pooltoy-a-toy-process-pool-manager-in-elixir-1-6/
Another possibility is to use a hybrid approach where Supervisor starts Main. Then Main will create a registry instance, and start its siblings with https://hexdocs.pm/elixir/1.6/Supervisor.html#start_child/2 where the provided child spec contains the registry name within the :start value.
xlphs
I usually name my GenServer like {:global, {:whatever_name, unique_id}}, then at runtime, look up pid with GenServer.whereis/1, do that every time you need to send a message, just in case the process was restarted in between. If only one instance will be running, use __MODULE__ works too and saves the lookup.
I doubt you need Registry for this.
xlphs
I think you are looking for https://github.com/uwiger/gproc , one of its feature is “Register a process under several aliases”







