Browse Source

Ensure that no double monitors are created after scope process crash.

Roberto Ostinelli 3 years ago
parent
commit
b42f8092a7
1 changed files with 13 additions and 5 deletions
  1. 13 5
      src/syn_registry.erl

+ 13 - 5
src/syn_registry.erl

@@ -343,17 +343,25 @@ rebuild_monitors(#state{
     table_by_pid = TableByPid
 }) ->
     RegistryTuples = get_registry_tuples_for_node(node(), TableByName),
-    lists:foreach(fun({Name, Pid, Meta, Time}) ->
+    lists:foldl(fun({Name, Pid, Meta, Time}, NewMonitorRefs) ->
         remove_from_local_table(Name, Pid, TableByName, TableByPid),
         case is_process_alive(Pid) of
             true ->
-                MRef = erlang:monitor(process, Pid),
-                add_to_local_table(Name, Pid, Meta, Time, MRef, TableByName, TableByPid);
+                case maps:find(Pid, NewMonitorRefs) of
+                    error ->
+                        MRef = erlang:monitor(process, Pid),
+                        add_to_local_table(Name, Pid, Meta, Time, MRef, TableByName, TableByPid),
+                        maps:put(Pid, MRef, NewMonitorRefs);
+
+                    {ok, MRef} ->
+                        add_to_local_table(Name, Pid, Meta, Time, MRef, TableByName, TableByPid),
+                        NewMonitorRefs
+                end;
 
             _ ->
-                ok
+                NewMonitorRefs
         end
-    end, RegistryTuples).
+    end, #{}, RegistryTuples).
 
 -spec get_registry_tuples_for_node(Node :: node(), TableByName :: atom()) -> [syn_registry_tuple()].
 get_registry_tuples_for_node(Node, TableByName) ->