Browse Source

Refactor registration conflict resolution.

Roberto Ostinelli 5 years ago
parent
commit
5d81664965
2 changed files with 73 additions and 90 deletions
  1. 2 2
      src/syn_event_handler.erl
  2. 71 88
      src/syn_registry.erl

+ 2 - 2
src/syn_event_handler.erl

@@ -93,8 +93,8 @@ do_on_group_process_exit(GroupName, Pid, Meta, Reason, CustomEventHandler) ->
 
 
 -spec do_resolve_registry_conflict(
 -spec do_resolve_registry_conflict(
     Name :: any(),
     Name :: any(),
-    {Pid1 :: pid(), Meta1 :: any()},
-    {Pid2 :: pid(), Meta2 :: any()},
+    {LocalPid :: pid(), LocalMeta :: any()},
+    {RemotePid :: pid(), RemoteMeta :: any()},
     CustomEventHandler :: module()
     CustomEventHandler :: module()
 ) -> {PidToKeep :: pid() | undefined, KillOther :: boolean()}.
 ) -> {PidToKeep :: pid() | undefined, KillOther :: boolean()}.
 do_resolve_registry_conflict(Name, {LocalPid, LocalMeta}, {RemotePid, RemoteMeta}, CustomEventHandler) ->
 do_resolve_registry_conflict(Name, {LocalPid, LocalMeta}, {RemotePid, RemoteMeta}, CustomEventHandler) ->

+ 71 - 88
src/syn_registry.erl

@@ -333,72 +333,88 @@ add_remote_to_local_table(Name, RemotePid, RemoteMeta) ->
                     %% get entry (for first node entering lock it exists, for subsequent nodes too
                     %% get entry (for first node entering lock it exists, for subsequent nodes too
                     %% because of data written during resolve)
                     %% because of data written during resolve)
                     Entry = find_process_entry_by_name(Name),
                     Entry = find_process_entry_by_name(Name),
-                    PidInTable = Entry#syn_registry_table.pid,
-                    MetaInTable = Entry#syn_registry_table.meta,
-
-                    case PidInTable =:= RemotePid of
+                    case Entry#syn_registry_table.pid =:= RemotePid of
                         true ->
                         true ->
                             error_logger:info_msg(
                             error_logger:info_msg(
                                 "Syn(~p): Conflicting name from multicast ~p already resolved, skipping~n",
                                 "Syn(~p): Conflicting name from multicast ~p already resolved, skipping~n",
                                 [node(), Name]
                                 [node(), Name]
                             );
                             );
                         false ->
                         false ->
+                            LocalPid = Entry#syn_registry_table.pid,
+                            LocalMeta = Entry#syn_registry_table.meta,
                             error_logger:warning_msg(
                             error_logger:warning_msg(
                                 "Syn(~p): Conflicting name from multicast found for: ~p, processes are ~p, ~p~n",
                                 "Syn(~p): Conflicting name from multicast found for: ~p, processes are ~p, ~p~n",
-                                [node(), Name, PidInTable, RemotePid]
+                                [node(), Name, LocalPid, RemotePid]
                             ),
                             ),
 
 
-
+                            %% TODO: get handler
                             CustomEventHandler = undefined,
                             CustomEventHandler = undefined,
 
 
 
 
-                            %% call conflict resolution
-                            {PidToKeep, KillOther} = syn_event_handler:do_resolve_registry_conflict(
-                                Name,
-                                {PidInTable, MetaInTable},
-                                {RemotePid, RemoteMeta},
-                                CustomEventHandler
-                            ),
-
-                            %% keep chosen one
-                            case PidToKeep of
-                                PidInTable ->
-                                    %% keep local
-                                    error_logger:error_msg(
-                                        "Syn(~p): Keeping local process ~p, killing remote ~p~n",
-                                        [node(), PidInTable, RemotePid]
-                                    ),
+                            resolve_conflict(Name, {LocalPid, LocalMeta}, {RemotePid, RemoteMeta}, CustomEventHandler,
+                                fun() ->
                                     RemoteNode = node(RemotePid),
                                     RemoteNode = node(RemotePid),
-                                    ok = rpc:call(RemoteNode, syn_registry, add_to_local_table, [Name, PidInTable, MetaInTable, undefined]),
-                                    case KillOther of
-                                        true -> exit(RemotePid, kill);
-                                        _ -> ok
-                                    end;
-
-                                RemotePid ->
-                                    %% keep remote
-                                    error_logger:error_msg(
-                                        "Syn(~p): Keeping remote process ~p, killing local ~p~n",
-                                        [node(), RemotePid, PidInTable]
-                                    ),
-                                    add_to_local_table(Name, RemotePid, RemoteMeta, undefined),
-                                    case KillOther of
-                                        true -> exit(PidInTable, kill);
-                                        _ -> ok
-                                    end;
-
-                                Other ->
-                                    error_logger:error_msg(
-                                        "Syn(~p): Custom handler returned ~p, valid options were ~p and ~p~n",
-                                        [node(), Other, PidInTable, RemotePid]
-                                    )
-                            end
-
+                                    ok = rpc:call(RemoteNode, syn_registry, add_to_local_table, [Name, LocalPid, LocalMeta, undefined])
+                                end,
+                                fun() ->
+                                    add_to_local_table(Name, RemotePid, RemoteMeta, undefined)
+                                end
+                            )
                     end
                     end
                 end
                 end
             )
             )
     end.
     end.
 
 
+-spec resolve_conflict(
+    Name :: any(),
+    {LocalPid :: pid(), LocalMeta :: any()},
+    {RemotePid :: pid(), RemoteMeta :: any()},
+    CustomEventHandler :: module(),
+    KeepLocalFun :: fun(),
+    KeepRemoteFun :: fun()
+) -> ok.
+resolve_conflict(Name, {LocalPid, LocalMeta}, {RemotePid, RemoteMeta}, CustomEventHandler, KeepLocalFun, KeepRemoteFun) ->
+    %% call conflict resolution
+    {PidToKeep, KillOther} = syn_event_handler:do_resolve_registry_conflict(
+        Name,
+        {LocalPid, LocalMeta},
+        {RemotePid, RemoteMeta},
+        CustomEventHandler
+    ),
+
+    %% keep chosen one
+    case PidToKeep of
+        LocalPid ->
+            %% keep local
+            error_logger:error_msg(
+                "Syn(~p): Keeping local process ~p, killing remote ~p~n",
+                [node(), LocalPid, RemotePid]
+            ),
+            KeepLocalFun(),
+            case KillOther of
+                true -> exit(RemotePid, kill);
+                _ -> ok
+            end;
+
+        RemotePid ->
+            %% keep remote
+            error_logger:error_msg(
+                "Syn(~p): Keeping remote process ~p, killing local ~p~n",
+                [node(), RemotePid, LocalPid]
+            ),
+            KeepRemoteFun(),
+            case KillOther of
+                true -> exit(LocalPid, kill);
+                _ -> ok
+            end;
+
+        Other ->
+            error_logger:error_msg(
+                "Syn(~p): Custom handler returned ~p, valid options were ~p and ~p~n",
+                [node(), Other, LocalPid, RemotePid]
+            )
+    end.
+
 -spec remove_from_local_table(Name :: any()) -> ok.
 -spec remove_from_local_table(Name :: any()) -> ok.
 remove_from_local_table(Name) ->
 remove_from_local_table(Name) ->
     mnesia:dirty_delete(syn_registry_table, Name).
     mnesia:dirty_delete(syn_registry_table, Name).
@@ -467,47 +483,14 @@ sync_registry_tuples(RemoteNode, RegistryTuples, #state{
                     [node(), Name, LocalPid, RemotePid]
                     [node(), Name, LocalPid, RemotePid]
                 ),
                 ),
 
 
-                %% call conflict resolution
-                {PidToKeep, KillOther} = syn_event_handler:do_resolve_registry_conflict(
-                    Name,
-                    {LocalPid, LocalMeta},
-                    {RemotePid, RemoteMeta},
-                    CustomEventHandler
-                ),
-
-                %% keep chosen one
-                case PidToKeep of
-                    LocalPid ->
-                        %% keep local
-                        error_logger:error_msg(
-                            "Syn(~p): Keeping local process ~p, killing remote ~p~n",
-                            [node(), LocalPid, RemotePid]
-                        ),
-                        ok = rpc:call(RemoteNode, syn_registry, remove_from_local_table, [Name]),
-                        case KillOther of
-                            true -> exit(RemotePid, kill);
-                            _ -> ok
-                        end;
-
-                    RemotePid ->
-                        %% keep remote
-                        error_logger:error_msg(
-                            "Syn(~p): Keeping remote process ~p, killing local ~p~n",
-                            [node(), RemotePid, LocalPid]
-                        ),
-                        remove_from_local_table(Name),
-                        add_to_local_table(Name, RemotePid, RemoteMeta, undefined),
-                        case KillOther of
-                            true -> exit(LocalPid, kill);
-                            _ -> ok
-                        end;
-
-                    Other ->
-                        error_logger:error_msg(
-                            "Syn(~p): Custom handler returned ~p, valid options were ~p and ~p",
-                            [node(), Other, LocalPid, RemotePid]
-                        )
-                end
+                resolve_conflict(Name, {LocalPid, LocalMeta}, {RemotePid, RemoteMeta}, CustomEventHandler,
+                    fun() ->
+                        ok = rpc:call(RemoteNode, syn_registry, remove_from_local_table, [Name])
+                    end,
+                    fun() ->
+                        add_to_local_table(Name, RemotePid, RemoteMeta, undefined)
+                    end
+                )
         end
         end
     end,
     end,
     %% add to table
     %% add to table