|
@@ -217,10 +217,12 @@ handle_cast({inconsistent_name_data, OriginatingNode, Name, RemotePid, RemoteMet
|
|
resolve_conflict(Name, {TablePid, TableMeta}, {RemotePid, RemoteMeta},
|
|
resolve_conflict(Name, {TablePid, TableMeta}, {RemotePid, RemoteMeta},
|
|
%% keep currently in table
|
|
%% keep currently in table
|
|
fun() ->
|
|
fun() ->
|
|
|
|
+ %% overwrite
|
|
ok = rpc:call(OriginatingNode, syn_registry, add_to_local_table, [Name, TablePid, TableMeta, undefined])
|
|
ok = rpc:call(OriginatingNode, syn_registry, add_to_local_table, [Name, TablePid, TableMeta, undefined])
|
|
end,
|
|
end,
|
|
%% keep remote
|
|
%% keep remote
|
|
fun() ->
|
|
fun() ->
|
|
|
|
+ %% overwrite
|
|
add_to_local_table(Name, RemotePid, RemoteMeta, undefined)
|
|
add_to_local_table(Name, RemotePid, RemoteMeta, undefined)
|
|
end,
|
|
end,
|
|
State
|
|
State
|
|
@@ -290,7 +292,12 @@ handle_info({nodeup, RemoteNode}, State) ->
|
|
case find_process_entry_by_name(Name) of
|
|
case find_process_entry_by_name(Name) of
|
|
undefined ->
|
|
undefined ->
|
|
%% no conflict
|
|
%% no conflict
|
|
- register_on_node(Name, RemotePid, RemoteMeta);
|
|
|
|
|
|
+ case rpc:call(node(RemotePid), erlang, is_process_alive, [RemotePid]) of
|
|
|
|
+ true ->
|
|
|
|
+ register_on_node(Name, RemotePid, RemoteMeta);
|
|
|
|
+ _ ->
|
|
|
|
+ ok
|
|
|
|
+ end;
|
|
|
|
|
|
Entry ->
|
|
Entry ->
|
|
LocalPid = Entry#syn_registry_table.pid,
|
|
LocalPid = Entry#syn_registry_table.pid,
|
|
@@ -469,16 +476,40 @@ handle_process_down(Name, Pid, Meta, Reason, #state{
|
|
KeepRemoteFun :: fun(),
|
|
KeepRemoteFun :: fun(),
|
|
#state{}
|
|
#state{}
|
|
) -> ok.
|
|
) -> ok.
|
|
-resolve_conflict(Name, {TablePid, TableMeta}, {RemotePid, RemoteMeta}, KeepTableFun, KeepRemoteFun, #state{
|
|
|
|
- custom_event_handler = CustomEventHandler
|
|
|
|
-}) ->
|
|
|
|
- %% call conflict resolution
|
|
|
|
- {PidToKeep, KillOther} = syn_event_handler:do_resolve_registry_conflict(
|
|
|
|
- Name,
|
|
|
|
- {TablePid, TableMeta},
|
|
|
|
- {RemotePid, RemoteMeta},
|
|
|
|
- CustomEventHandler
|
|
|
|
- ),
|
|
|
|
|
|
+resolve_conflict(
|
|
|
|
+ Name,
|
|
|
|
+ {TablePid, TableMeta},
|
|
|
|
+ {RemotePid, RemoteMeta},
|
|
|
|
+ KeepTableFun,
|
|
|
|
+ KeepRemoteFun,
|
|
|
|
+ #state{custom_event_handler = CustomEventHandler}
|
|
|
|
+) ->
|
|
|
|
+ TablePidAlive = rpc:call(node(TablePid), erlang, is_process_alive, [TablePid]),
|
|
|
|
+ RemotePidAlive = rpc:call(node(RemotePid), erlang, is_process_alive, [RemotePid]),
|
|
|
|
+
|
|
|
|
+ %% check if pids are alive (race conditions if pid dies during resolution)
|
|
|
|
+ {PidToKeep, KillOther} = case {TablePidAlive, RemotePidAlive} of
|
|
|
|
+ {true, true} ->
|
|
|
|
+ %% call conflict resolution
|
|
|
|
+ syn_event_handler:do_resolve_registry_conflict(
|
|
|
|
+ Name,
|
|
|
|
+ {TablePid, TableMeta},
|
|
|
|
+ {RemotePid, RemoteMeta},
|
|
|
|
+ CustomEventHandler
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ {true, false} ->
|
|
|
|
+ %% keep only alive process
|
|
|
|
+ {TablePid, false};
|
|
|
|
+
|
|
|
|
+ {false, true} ->
|
|
|
|
+ %% keep only alive process
|
|
|
|
+ {RemotePidAlive, false};
|
|
|
|
+
|
|
|
|
+ {false, false} ->
|
|
|
|
+ %% remove both
|
|
|
|
+ {none, false}
|
|
|
|
+ end,
|
|
|
|
|
|
%% keep chosen one
|
|
%% keep chosen one
|
|
case PidToKeep of
|
|
case PidToKeep of
|
|
@@ -506,6 +537,11 @@ resolve_conflict(Name, {TablePid, TableMeta}, {RemotePid, RemoteMeta}, KeepTable
|
|
end,
|
|
end,
|
|
KeepRemoteFun();
|
|
KeepRemoteFun();
|
|
|
|
|
|
|
|
+ none ->
|
|
|
|
+ remove_from_local_table(Name),
|
|
|
|
+ RemoteNode = node(RemotePid),
|
|
|
|
+ ok = rpc:call(RemoteNode, syn_registry, remove_from_local_table, [Name]);
|
|
|
|
+
|
|
Other ->
|
|
Other ->
|
|
error_logger:error_msg(
|
|
error_logger:error_msg(
|
|
"Syn(~p): Custom handler returned ~p, valid options were ~p and ~p~n",
|
|
"Syn(~p): Custom handler returned ~p, valid options were ~p and ~p~n",
|