emqx / eip

EMQX Improvement Proposals
21 stars 19 forks source link

cluster-call: how to confirm that the commit has succeeded #43

Closed zhongwencool closed 3 years ago

zhongwencool commented 3 years ago

Alternative

Don't send back results, just check periodically. This will not require adding new fields

confirm_commit({ok, TnxId, _Res}, all, Timeout)when Timeout =< 0  ->
    case transaction(fun node_not_commit/1, [TnxId]) of
        {atomic, []} -> ok;
        {atomic, Nodes} -> {error, Nodes}
    end;
confirm_commit({ok, TnxId, _Res} = Init, all, Timeout)  ->
    timer:sleep(150),
    case transaction(fun node_not_commit/1, [TnxId]) of
        {atomic, []} -> ok;
        {atomic, _} -> confirm_commit(Init, all, Timeout - 150)
    end;

confirm_commit({ok, TnxId, _Res}, SucceedNum, Timeout) when Timeout =< 0 ->
    case transaction(fun node_already_commit/1, [TnxId]) of
        {atomic, Nodes} when length(Nodes) >= SucceedNum -> ok;
        {atomic, Nodes} -> {error, Nodes}
    end;
confirm_commit({ok, TnxId, _Res} = Init, SucceedNum, Timeout)  ->
    timer:sleep(150),
    case transaction(fun node_already_commit/1, [TnxId]) of
        {atomic, Nodes} when length(Nodes) >= SucceedNum -> ok;
        {atomic, _} -> confirm_commit(Init, SucceedNum, Timeout - 150)
    end.

node_not_commit(TnxId) ->
    MatchHead = #cluster_rpc_commit{tnx_id = '$1', node = '$2', _='_'},
    Guard = {'<', '$1', TnxId},
    Result = '$2',
    Nodes = mnesia:select(?CLUSTER_COMMIT, [{MatchHead, [Guard], [Result]}]),
    lists:flatten(Nodes).

node_already_commit(TnxId) ->
    MatchHead = #cluster_rpc_commit{tnx_id = '$1', node = '$2', _='_'},
    Guard = {'>=', '$1', TnxId},
    Result = '$2',
    Nodes = mnesia:select(?CLUSTER_COMMIT, [{MatchHead, [Guard], [Result]}]),
    lists:flatten(Nodes).

Disadvantages in the first scenario:

we send the message back as in the first scenario: If there are 6 nodes in the cluster when setting succeedNum=2, it succeeds when 2 messages are received, and there are 4 messages that I don't know how to discard.