Если вам нужно довольно простое решение, которое работает с глобальным реестром процессов, вы можете изменить свой динамический супервизор start_link
defmodule EcompackingCore.PackerSupervisor do
use DynamicSupervisor
require Logger
def start_link() do
case DynamicSupervisor.start_link(__MODULE__, :ok, name: {:global, :packer_supervisor}) do
{:ok, pid} ->
{:ok, pid}
{:error, {:already_started, pid}} ->
# you need this pid so on each node supervisor
# of this dynamic supervisor can monitor this same pid
# so each node tracks existence of your process
{:ok, pid}
any -> any
end
end
def init(:ok) do
Logger.info("Starting Packer Supervisor")
DynamicSupervisor.init(strategy: :one_for_one)
end
def add_packer(badge_id, packer_name) do
child_spec = {EcompackingCore.Packer, {badge_id, packer_name}}
DynamicSupervisor.start_child(:global.whereis_name(:packer_supervisor), child_spec)
end
def remove_packer(packer_pid) do
DynamicSupervisor.terminate_child(:global.whereis_name(:packer_supervisor), packer_pid)
end
def children do
DynamicSupervisor.which_children(:global.whereis_name(:packer_supervisor))
end
def count_children do
DynamicSupervisor.count_children(:global.whereis_name(:packer_supervisor))
end
end
Что многие скажут об этом решении, так это то, что вам не следует делать этого, поскольку в случаеразделения сети, вы в конечном итоге с двумя или более глобальными процессами в кластере.Но вы даже можете справиться с этим, если внедрите какой-нибудь узел мониторинга / отслеживания, чтобы вы знали, сколько узлов вы «видите» в кластере.
Например, если размер кластера iz 5, вы можете создать правило проверки, которое проверит, видите ли вы более 3 узлов, если нет, то вы запланируете следующий запуск, скажем, в течение 1 секунды, и попытаетесь зарегистрироваться снова глобально.ваш динамический супервизор до тех пор, пока правило проверки не вернет true (это означает, что вы находитесь в мажоритарной группе, и вы можете предложить согласованность в этой группе).С другой стороны, если ваш узел принадлежит к группе меньшинств и уже содержит глобальный динамический супервизор, выключите его и запланируйте запуск через 1 секунду.
Это самый простой способ достижения согласованности в кластере, но есть одна вещь, которую выследует рассмотреть.Этот Dynamic Supervisor начнет работу на одном узле, который, я уверен, вам не нужен, поэтому лучше использовать глобальный реестр и некоторый алгоритм балансировки нагрузки, чтобы сбалансировать процессы, которые должны быть запущены в локальных супервизорах.
- Swarm имеет встроенные алгоритмы кольца и статического кольца кворума, но использует хеширование для распределения нагрузки по кластеру.Это хорошее решение, если у ваших работников есть ID, для которого вы можете вычислить хеш.
- Син является другой альтернативой.