Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support different cluster topologies #79

Open
derekkraan opened this issue Mar 23, 2019 · 4 comments
Open

Support different cluster topologies #79

derekkraan opened this issue Mar 23, 2019 · 4 comments
Labels
enhancement New feature or request

Comments

@derekkraan
Copy link
Owner

Currently every node is connected to every other node (via delta_crdt). It should be possible to define other topologies to make synchronization more efficient.

@derekkraan derekkraan added the enhancement New feature or request label Mar 23, 2019
@beardedeagle
Copy link

Has any thought been given about how libraries like libcluster or partisan would come into play here?

@derekkraan
Copy link
Owner Author

I think libcluster is complimentary to Horde.

If it's going to mean anything for this feature, then it'll have to be a new feature in libcluster I think.

I haven't given much thought to partisan, I'm not 100% sure what it actually is / does.

@shikanime
Copy link
Contributor

shikanime commented Jul 29, 2019

If I understood correctly, here is an example of how i use the libcluster callbacks to form my Horde cluster and connect to the rest as another service in a microservices cluster using another topology:

el

topologies = [
  replicas: [
    strategy: Cluster.Strategy.Gossip,
    config: [secret: "my-secret"],
    connect: {MyApp.HordeFederation, :connect, [MyApp.HordeFederation]},
    disconnect: {MyApp.HordeFederation, :disconnect, [MyApp.HordeFederation]}
  ],
  my_other_service: [
    strategy: Cluster.Strategy.Gossip,
    config: [secret: "my-secret-for-other-service"],
  ]
]
defmodule MyApp.HordeFederation do
  use GenServer

  defstruct cluster: nil,
            nodes: []

  def start_link(options \\ []) do
    keys = [:cluster]
    {server_opts, start_opts} = Keyword.split(options, keys)
    GenServer.start_link(__MODULE__, server_opts, start_opts)
  end

  def connect(federation, node) do
    GenServer.cast(federation, {:nodeup, node})
  end

  def disconnect(federation, node) do
    GenServer.cast(federation, {:nodedown, node})
  end

  def init(options) do
    :net_kernel.monitor_nodes(true)

    nodes = [Node.self()]
    cluster = Keyword.fetch!(options, :cluster)

    state = %__MODULE__{
      cluster: cluster,
      nodes: nodes
    }

    {:ok, state, {:continue, :recluster}}
  end

  def handle_continue(:recluster, state) do
    Horde.Cluster.set_members(
      state.cluster,
      Enum.map(state.nodes, &{state.cluster, &1})
    )

    {:noreply, state}
  end

  def handle_info({:nodedown, node}, state) do
    nodes = state.nodes -- node
    state = %{state | nodes: nodes}
    {:noreply, state, {:continue, :recluster}}
  end

  def handle_info({:nodeup, node}, state) do
    nodes = [node | state.nodes]
    state = %{state | nodes: nodes}
    {:noreply, state, {:continue, :recluster}}
  end
end

@derekkraan
Copy link
Owner Author

To clarify this issue, currently Horde sets up delta_crdt in a mesh network that mirrors the erlang cluster 1:1. This is not necessarily the most efficient way to set up a network, and that's why you have a project like partisan, which can work with other topologies.

Because a mesh network has O(n^2) connections, it does not scale well. There are other topologies possible, such as a ring topology, with O(n) connections, or a tree topology, also O(n). Partially connected mesh is also possible, with something in between.

Anyways, using Partisan could be a possibility in the future for even larger clusters, but we could start with this feature, adding the ability to hook up the underlying delta_crdt in different cluster topologies.

So this issue isn't about libcluster topologies, but about the topology of the delta_crdt network underpinning Horde.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants