Distributed writes need coordinated calls and bounded waiting. :rpc.multicall/4 invokes an MFA function across cluster nodes, collects responses, and returns {results, bad_nodes}. section 12.2.3
Use it with production failure boundaries in mind:
- Always provide a timeout; otherwise the operation can block forever. section 12.2.3
- Treat bad_nodes as partial failure, then verify that successful responses are actually :ok. section 12.2.3
Replicating a database write
def store(key, data) do {_results, bad_nodes} = :rpc.multicall(__MODULE__, :store_local, [key, data], :timer.seconds(5)) Enum.each(bad_nodes, &IO.puts("Store failed on node #{&1}")) :ok end section 12.2.3
Listing 12.5 Storing data on all nodes (todo_distributed/lib/todo/database.ex)
defmodule Todo.Database do
...
def store(key, data) do
{_results, bad_nodes} =
:rpc.multicall( #1
__MODULE__, #1
:store_local, #1
[key, data], #1
:timer.seconds(5) #1
) #1
Enum.each(bad_nodes, &IO.puts("Store failed on node #{&1}")) #2
:ok
end
...
end
Shows the complete store operation and its timeout and failed-node handling. section 12.2.3
