Ordered messaging via multiple gen_rpc clients
This commit is contained in:
parent
eb2fec884c
commit
3405dbaf5c
|
@ -258,7 +258,7 @@ aggre(Routes) ->
|
||||||
-spec(forward(node(), emqx_types:topic(), emqx_types:delivery(), RPCMode::sync|async)
|
-spec(forward(node(), emqx_types:topic(), emqx_types:delivery(), RPCMode::sync|async)
|
||||||
-> emqx_types:deliver_result()).
|
-> emqx_types:deliver_result()).
|
||||||
forward(Node, To, Delivery, async) ->
|
forward(Node, To, Delivery, async) ->
|
||||||
case emqx_rpc:cast(Node, ?BROKER, dispatch, [To, Delivery]) of
|
case emqx_rpc:cast(To, Node, ?BROKER, dispatch, [To, Delivery]) of
|
||||||
true -> ok;
|
true -> ok;
|
||||||
{badrpc, Reason} ->
|
{badrpc, Reason} ->
|
||||||
?LOG(error, "Ansync forward msg to ~s failed: ~p", [Node, Reason]),
|
?LOG(error, "Ansync forward msg to ~s failed: ~p", [Node, Reason]),
|
||||||
|
@ -266,7 +266,7 @@ forward(Node, To, Delivery, async) ->
|
||||||
end;
|
end;
|
||||||
|
|
||||||
forward(Node, To, Delivery, sync) ->
|
forward(Node, To, Delivery, sync) ->
|
||||||
case emqx_rpc:call(Node, ?BROKER, dispatch, [To, Delivery]) of
|
case emqx_rpc:call(To, Node, ?BROKER, dispatch, [To, Delivery]) of
|
||||||
{badrpc, Reason} ->
|
{badrpc, Reason} ->
|
||||||
?LOG(error, "Sync forward msg to ~s failed: ~p", [Node, Reason]),
|
?LOG(error, "Sync forward msg to ~s failed: ~p", [Node, Reason]),
|
||||||
{error, badrpc};
|
{error, badrpc};
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
-module(emqx_rpc).
|
-module(emqx_rpc).
|
||||||
|
|
||||||
-export([ call/4
|
-export([ call/4
|
||||||
|
, call/5
|
||||||
, cast/4
|
, cast/4
|
||||||
|
, cast/5
|
||||||
, multicall/4
|
, multicall/4
|
||||||
|
, multicall/5
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-compile({inline,
|
-compile({inline,
|
||||||
|
@ -34,15 +37,27 @@
|
||||||
call(Node, Mod, Fun, Args) ->
|
call(Node, Mod, Fun, Args) ->
|
||||||
filter_result(?RPC:call(rpc_node(Node), Mod, Fun, Args)).
|
filter_result(?RPC:call(rpc_node(Node), Mod, Fun, Args)).
|
||||||
|
|
||||||
|
call(Key, Node, Mod, Fun, Args) ->
|
||||||
|
filter_result(?RPC:call(rpc_node({Key, Node}), Mod, Fun, Args)).
|
||||||
|
|
||||||
multicall(Nodes, Mod, Fun, Args) ->
|
multicall(Nodes, Mod, Fun, Args) ->
|
||||||
filter_result(?RPC:multicall(rpc_nodes(Nodes), Mod, Fun, Args)).
|
filter_result(?RPC:multicall(rpc_nodes(Nodes), Mod, Fun, Args)).
|
||||||
|
|
||||||
|
multicall(Key, Nodes, Mod, Fun, Args) ->
|
||||||
|
filter_result(?RPC:multicall(rpc_nodes([{Key, Node} || Node <- Nodes]), Mod, Fun, Args)).
|
||||||
|
|
||||||
cast(Node, Mod, Fun, Args) ->
|
cast(Node, Mod, Fun, Args) ->
|
||||||
filter_result(?RPC:cast(rpc_node(Node), Mod, Fun, Args)).
|
filter_result(?RPC:cast(rpc_node(Node), Mod, Fun, Args)).
|
||||||
|
|
||||||
rpc_node(Node) ->
|
cast(Key, Node, Mod, Fun, Args) ->
|
||||||
|
filter_result(?RPC:cast(rpc_node({Key, Node}), Mod, Fun, Args)).
|
||||||
|
|
||||||
|
rpc_node(Node) when is_atom(Node) ->
|
||||||
ClientNum = application:get_env(gen_rpc, tcp_client_num, ?DefaultClientNum),
|
ClientNum = application:get_env(gen_rpc, tcp_client_num, ?DefaultClientNum),
|
||||||
{Node, rand:uniform(ClientNum)}.
|
{Node, rand:uniform(ClientNum)};
|
||||||
|
rpc_node({Key, Node}) when is_atom(Node) ->
|
||||||
|
ClientNum = application:get_env(gen_rpc, tcp_client_num, ?DefaultClientNum),
|
||||||
|
{Node, erlang:phash2(Key, ClientNum) + 1}.
|
||||||
|
|
||||||
rpc_nodes(Nodes) ->
|
rpc_nodes(Nodes) ->
|
||||||
rpc_nodes(Nodes, []).
|
rpc_nodes(Nodes, []).
|
||||||
|
|
|
@ -24,17 +24,6 @@
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
t_multicall(_) ->
|
|
||||||
error('TODO').
|
|
||||||
|
|
||||||
t_cast(_) ->
|
|
||||||
error('TODO').
|
|
||||||
|
|
||||||
t_call(_) ->
|
|
||||||
error('TODO').
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
t_prop_rpc(_) ->
|
t_prop_rpc(_) ->
|
||||||
ok = load(),
|
ok = load(),
|
||||||
Opts = [{to_file, user}, {numtests, 10}],
|
Opts = [{to_file, user}, {numtests, 10}],
|
||||||
|
@ -42,7 +31,9 @@ t_prop_rpc(_) ->
|
||||||
ok = application:set_env(gen_rpc, call_receive_timeout, 1),
|
ok = application:set_env(gen_rpc, call_receive_timeout, 1),
|
||||||
ok = emqx_logger:set_log_level(emergency),
|
ok = emqx_logger:set_log_level(emergency),
|
||||||
?assert(proper:quickcheck(prop_node(), Opts)),
|
?assert(proper:quickcheck(prop_node(), Opts)),
|
||||||
|
?assert(proper:quickcheck(prop_node_with_key(), Opts)),
|
||||||
?assert(proper:quickcheck(prop_nodes(), Opts)),
|
?assert(proper:quickcheck(prop_nodes(), Opts)),
|
||||||
|
?assert(proper:quickcheck(prop_nodes_with_key(), Opts)),
|
||||||
ok = application:stop(gen_rpc),
|
ok = application:stop(gen_rpc),
|
||||||
ok = unload().
|
ok = unload().
|
||||||
|
|
||||||
|
@ -57,6 +48,17 @@ prop_node() ->
|
||||||
end
|
end
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
prop_node_with_key() ->
|
||||||
|
?FORALL({Node, Key}, nodename_with_key(),
|
||||||
|
begin
|
||||||
|
?assert(emqx_rpc:cast(Key, Node, erlang, system_time, [])),
|
||||||
|
case emqx_rpc:call(Key, Node, erlang, system_time, []) of
|
||||||
|
{badrpc, _Reason} -> true;
|
||||||
|
Delivery when is_integer(Delivery) -> true;
|
||||||
|
_Other -> false
|
||||||
|
end
|
||||||
|
end).
|
||||||
|
|
||||||
prop_nodes() ->
|
prop_nodes() ->
|
||||||
?FORALL(Nodes, nodesname(),
|
?FORALL(Nodes, nodesname(),
|
||||||
begin
|
begin
|
||||||
|
@ -70,6 +72,19 @@ prop_nodes() ->
|
||||||
end
|
end
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
prop_nodes_with_key() ->
|
||||||
|
?FORALL({Nodes, Key}, nodesname_with_key(),
|
||||||
|
begin
|
||||||
|
case emqx_rpc:multicall(Key, Nodes, erlang, system_time, []) of
|
||||||
|
{badrpc, _Reason} -> true;
|
||||||
|
{RealResults, RealBadNodes}
|
||||||
|
when is_list(RealResults);
|
||||||
|
is_list(RealBadNodes) ->
|
||||||
|
true;
|
||||||
|
_Other -> false
|
||||||
|
end
|
||||||
|
end).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% helper
|
%% helper
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -96,8 +111,19 @@ nodename() ->
|
||||||
list_to_atom(Node)
|
list_to_atom(Node)
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
nodename_with_key() ->
|
||||||
|
?LET({NodePrefix, HostName, Key},
|
||||||
|
{node_prefix(), hostname(), choose(0, 10)},
|
||||||
|
begin
|
||||||
|
Node = NodePrefix ++ "@" ++ HostName,
|
||||||
|
{list_to_atom(Node), Key}
|
||||||
|
end).
|
||||||
|
|
||||||
nodesname() ->
|
nodesname() ->
|
||||||
oneof([list(nodename()), ["emqxct@127.0.0.1"]]).
|
oneof([list(nodename()), ['emqxct@127.0.0.1']]).
|
||||||
|
|
||||||
|
nodesname_with_key() ->
|
||||||
|
oneof([{list(nodename()), choose(0, 10)}, {['emqxct@127.0.0.1'], 1}]).
|
||||||
|
|
||||||
node_prefix() ->
|
node_prefix() ->
|
||||||
oneof(["emqxct", text_like()]).
|
oneof(["emqxct", text_like()]).
|
||||||
|
|
Loading…
Reference in New Issue