Roteamento transparente entre o nó local e o nó dono de um grafo (v0.3).
Stateless. Duas responsabilidades:
- Resolver a rota de cada operação: se o
confestá noRegistrylocal (modo:localou este nó é o dono em:horde) → fast path (chamada direta contra a ETS local, multi-reader, zero Horde/:erpc). Caso contrário →:erpc.callpara o nó dono. - Executar a operação no dono (
run_local/3): roda o mesmo código de hoje (Query,Writer,SegmentManager, ...) contra a ETS local. O que cruza a rede é comando + resultado, nunca acesso ao dado.
Por que :erpc.call e não um GenServer.call central: rotear leitura por um
único processo serializaria as leituras (mata o multi-reader). O :erpc.call
roda a função num processo novo no dono → ETS concorrente preservada.
Summary
Functions
Corpo de neighbors/4 extraído (rodava inline na API pública). Roda inteiro no
dono porque encadeia vários acessos à ETB (IdMap + SegmentManager).
Resolve a rota de um grafo: {:local, conf}, {:remote, owner_node, conf} ou
{:error, :graph_unavailable}.
Roteia uma leitura. Local → direto; remoto → :erpc.call no dono.
Propaga {:error, :graph_unavailable | :graph_timeout} no caminho remoto.
Roteia uma escrita. Política por op
Executa a operação no nó dono, contra a ETS local. Invocada via :erpc.
É o mesmo código de hoje; só muda onde roda.
Types
@type route() :: {:local, MeliGraph.Config.t()} | {:remote, node(), MeliGraph.Config.t()}
Functions
@spec do_neighbors(MeliGraph.Config.t(), term(), :outgoing | :incoming, keyword()) :: [term()]
Corpo de neighbors/4 extraído (rodava inline na API pública). Roda inteiro no
dono porque encadeia vários acessos à ETB (IdMap + SegmentManager).
Resolve a rota de um grafo: {:local, conf}, {:remote, owner_node, conf} ou
{:error, :graph_unavailable}.
Em contexto não-distribuído (sem cluster), um grafo ausente localmente
levanta ArgumentError — paridade exata com o single-node de hoje.
Roteia uma leitura. Local → direto; remoto → :erpc.call no dono.
Propaga {:error, :graph_unavailable | :graph_timeout} no caminho remoto.
Roteia uma escrita. Política por op:
insert_edgeremoto emtesting: :disabled→:erpc.cast(fire-and-forget, espelha oGenServer.castlocal); em:sync→:erpc.call. Grafo indisponível → dropa com warning (a fonte da verdade é o Postgres +on_ready, que faz replay).- demais escritas →
:erpc.call.
Executa a operação no nó dono, contra a ETS local. Invocada via :erpc.
É o mesmo código de hoje; só muda onde roda.