diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index c33b366a6..e87d307e2 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -146,10 +146,9 @@ send_error(#{lserver := LServer} = State, Pkt, Err) -> {Pkt1, State1} -> xmpp_stream_in:send_error(State1, Pkt1, Err) end. --spec route(pid(), term()) -> ok. +-spec route(pid(), term()) -> boolean(). route(Pid, Term) -> - Pid ! Term, - ok. + ejabberd_cluster:send(Pid, Term). -spec set_timeout(state(), timeout()) -> state(). set_timeout(State, Timeout) -> diff --git a/src/ejabberd_cluster.erl b/src/ejabberd_cluster.erl index d9429a108..886c35377 100644 --- a/src/ejabberd_cluster.erl +++ b/src/ejabberd_cluster.erl @@ -113,21 +113,28 @@ get_node_by_id(ID) -> Mod = get_mod(), Mod:get_node_by_id(ID). +%% Note that false positive returns are possible, while false negatives are not. +%% In other words: positive return value (i.e. 'true') doesn't guarantee +%% successful delivery, while negative return value ('false') means +%% the delivery has definitely failed. -spec send(dst(), term()) -> boolean(). -send(Dst, Msg) -> - IsLocal = case Dst of - {_, Node} -> Node == node(); - Pid when is_pid(Pid) -> node(Pid) == node(); - Name when is_atom(Name) -> true; - _ -> false - end, - if IsLocal -> - erlang:send(Dst, Msg), +send({Name, Node}, Msg) when Node == node() -> + send(Name, Msg); +send(undefined, _Msg) -> + false; +send(Name, Msg) when is_atom(Name) -> + send(whereis(Name), Msg); +send(Pid, Msg) when is_pid(Pid) andalso node(Pid) == node() -> + case erlang:is_process_alive(Pid) of + true -> + erlang:send(Pid, Msg), true; - true -> - Mod = get_mod(), - Mod:send(Dst, Msg) - end. + false -> + false + end; +send(Dst, Msg) -> + Mod = get_mod(), + Mod:send(Dst, Msg). -spec wait_for_sync(timeout()) -> ok | {error, any()}. wait_for_sync(Timeout) ->