Are RPC calls the only solution for accessing locally registered processes across nodes using a hash ring?

Hi everyone,

I’m working on a distributed Elixir application where I use a hash ring to distribute processes across multiple nodes. Each node has processes that are registered locally using Registry, and they’re identified by a unique name. I want to send messages to these processes based on the hash ring mapping.

Here’s a simplified version of my code:

defmodule Worker do
  use GenServer

  def start_link(name) do
    # Start the GenServer and register it locally
    GenServer.start_link(__MODULE__, [], name: via_tuple(name))
  end

  def send_message(name, message) do
    # Get the target node from the hash ring
    target_node = HashRing.get_node(name)
    
    # Attempt to send a message to the process on the target node
    GenServer.cast({target_node, via_tuple(name)}, {:message, message})
  end

  # Helper for local registration via Registry
  defp via_tuple(name) do
    {:via, Registry, {MyApp.Registry, name}}
  end

  # Callbacks
  def init(_) do
    {:ok, %{}}
  end

  def handle_cast({:message, message}, state) do
    IO.puts("Received message on node #{Node.self()}: #{message}")
    {:noreply, state}
  end
end

The issue I’m facing is that since Registry is local to each node, the GenServer.cast doesn’t reach the process on the remote node because it tries to resolve the name locally. I found that using an RPC call works:

def send_message(name, message) do
  target_node = HashRing.get_node(name)
  :rpc.call(target_node, GenServer, :cast, [via_tuple(name), {:message, message}])
end

However, I’m wondering:

  1. Is using RPC calls the only solution to send messages to processes registered locally on other nodes?

  2. Can I configure Registry to be distributed across nodes so that I can avoid using RPC?

  3. Are there better patterns or best practices for accessing named processes on remote nodes when using local registries and a hash ring?

I’ve considered using a distributed Registry or :global for process registration, but I’m concerned about scalability and potential bottlenecks.

Any advice or suggestions on how to effectively communicate with locally registered processes across nodes would be greatly appreciated!

Thanks in advance!