derekkraan / horde

Horde is a distributed Supervisor and Registry backed by DeltaCrdt
MIT License
1.32k stars 106 forks source link

Truing up registry documentation with dynamic supervisor module #169

Closed jeffgrunewald closed 5 years ago

jeffgrunewald commented 5 years ago

Per discussion in https://github.com/derekkraan/horde/issues/165

derekkraan commented 5 years ago

Thanks!

jfrolich commented 5 years ago

Hmm this doesn't really work, aside from the typo (missed do) I get this:

** (Mix) Could not start application family_five: FamilyFive.Application.start(:normal, []) returned an error: shutdown: failed to start child: FamilyFive.HordeRegistry
    ** (EXIT) shutdown: failed to start child: nil
        ** (EXIT) an exception was raised:
            ** (ArgumentError) expected :name to be given and to be an atom, got: nil
                (horde) lib/horde/registry_impl.ex:33: Horde.RegistryImpl.start_link/1
                (stdlib) supervisor.erl:379: :supervisor.do_start_child_i/3
                (stdlib) supervisor.erl:365: :supervisor.do_start_child/2
                (stdlib) supervisor.erl:349: anonymous fn/3 in :supervisor.start_children/2
                (stdlib) supervisor.erl:1157: :supervisor.children_map/4
                (stdlib) supervisor.erl:315: :supervisor.init_children/2
                (stdlib) gen_server.erl:374: :gen_server.init_it/2
                (stdlib) gen_server.erl:342: :gen_server.init_it/6
                (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
jfrolich commented 5 years ago

This is my entry in application.ex

{FamilyFive.HordeRegistry, [name: FamilyFive.HordeRegistry, keys: :unique]},
derekkraan commented 5 years ago

@jfrolich which version of Horde are you running?

derekkraan commented 5 years ago

If I start a new application and add Horde as a dependency, and this line to my application's children, then it works just fine: {Horde.Registry, [name: MyHordeRegistry, keys: :unique]}

derekkraan commented 5 years ago

Ah, please paste in the contents of FamilyFive.HordeRegistry.

jfrolich commented 5 years ago

Got it working examples are not working because the arguments are passed in wrong. Also fixed a few issues in the examples of HordeSuperVisor and NodeListener.

defmodule FamilyFive.HordeRegistry do
  use Horde.Registry

  def start_link(_) do
    Horde.Registry.start_link(__MODULE__, [keys: :unique], name: __MODULE__)
  end

  def init(init_arg) do
    [members: members()]
    |> Keyword.merge(init_arg)
    |> Horde.Registry.init()
  end

  defp members() do
    [Node.self() | Node.list()]
    |> Enum.map(fn node -> {FamilyFive.HordeRegistry, node} end)
  end
end

Supervisor:

defmodule FamilyFive.HordeSupervisor do
  use Horde.DynamicSupervisor

  def start_link(_) do
    Horde.DynamicSupervisor.start_link(
      __MODULE__,
      [strategy: :one_for_one],
      name: __MODULE__
    )
  end

  def init(init_arg) do
    [members: members()]
    |> Keyword.merge(init_arg)
    |> Horde.DynamicSupervisor.init()
  end

  defp members() do
    [Node.self() | Node.list()]
    |> Enum.map(fn node -> {__MODULE__, node} end)
  end
end

Node listener:

defmodule FamilyFive.HordeNodeListener do
  use GenServer

  def start_link(_), do: GenServer.start_link(__MODULE__, [])

  def init(_) do
    :net_kernel.monitor_nodes(true, node_type: :visible)
    {:ok, nil}
  end

  def handle_info({:nodeup, _node, _node_type}, state) do
    set_members(FamilyFive.HordeRegistry)
    set_members(FamilyFive.HordeSupervisor)
    {:noreply, state}
  end

  def handle_info({:nodedown, _node, _node_type}, state) do
    set_members(FamilyFive.HordeRegistry)
    set_members(FamilyFive.HordeSupervisor)
    {:noreply, state}
  end

  defp set_members(name) do
    members =
      [Node.self() | Node.list()]
      |> Enum.map(fn node -> {name, node} end)

    :ok = Horde.Cluster.set_members(name, members)
  end
end
derekkraan commented 5 years ago

@jfrolich can you send a PR if examples are incorrect?