|
@@ -152,11 +152,16 @@ count(Scope, Node) ->
|
|
|
%% Init
|
|
|
%% ----------------------------------------------------------------------------------------------------------
|
|
|
-spec init(#state{}) -> {ok, HandlerState :: term()}.
|
|
|
-init(State) ->
|
|
|
- HandlerState = #{},
|
|
|
- %% rebuild
|
|
|
- rebuild_monitors(State),
|
|
|
+init(#state{
|
|
|
+ scope = Scope,
|
|
|
+ table_by_name = TableByName,
|
|
|
+ table_by_pid = TableByPid
|
|
|
+}) ->
|
|
|
+ %% purge remote & rebuild
|
|
|
+ purge_registry_for_remote_nodes(Scope, TableByName, TableByPid),
|
|
|
+ rebuild_monitors(TableByName, TableByPid),
|
|
|
%% init
|
|
|
+ HandlerState = #{},
|
|
|
{ok, HandlerState}.
|
|
|
|
|
|
%% ----------------------------------------------------------------------------------------------------------
|
|
@@ -319,35 +324,35 @@ purge_local_data_for_node(Node, #state{
|
|
|
%% ===================================================================
|
|
|
%% Internal
|
|
|
%% ===================================================================
|
|
|
--spec rebuild_monitors(#state{}) -> ok.
|
|
|
-rebuild_monitors(#state{
|
|
|
- table_by_name = TableByName
|
|
|
-} = State) ->
|
|
|
+-spec rebuild_monitors(TableByName :: atom(), TableByPid :: atom()) -> ok.
|
|
|
+rebuild_monitors(TableByName, TableByPid) ->
|
|
|
RegistryTuples = get_registry_tuples_for_node(node(), TableByName),
|
|
|
- do_rebuild_monitors(RegistryTuples, #{}, State).
|
|
|
+ do_rebuild_monitors(RegistryTuples, #{}, TableByName, TableByPid).
|
|
|
|
|
|
--spec do_rebuild_monitors([syn_registry_tuple()], #{pid() => reference()}, #state{}) -> ok.
|
|
|
-do_rebuild_monitors([], _, _) -> ok;
|
|
|
-do_rebuild_monitors([{Name, Pid, Meta, Time} | T], NewMonitorRefs, #state{
|
|
|
- table_by_name = TableByName,
|
|
|
- table_by_pid = TableByPid
|
|
|
-} = State) ->
|
|
|
+-spec do_rebuild_monitors(
|
|
|
+ [syn_registry_tuple()],
|
|
|
+ #{pid() => reference()},
|
|
|
+ TableByName :: atom(),
|
|
|
+ TableByPid :: atom()
|
|
|
+) -> ok.
|
|
|
+do_rebuild_monitors([], _, _, _) -> ok;
|
|
|
+do_rebuild_monitors([{Name, Pid, Meta, Time} | T], NewMRefs, TableByName, TableByPid) ->
|
|
|
remove_from_local_table(Name, Pid, TableByName, TableByPid),
|
|
|
case is_process_alive(Pid) of
|
|
|
true ->
|
|
|
- case maps:find(Pid, NewMonitorRefs) of
|
|
|
+ case maps:find(Pid, NewMRefs) of
|
|
|
error ->
|
|
|
MRef = erlang:monitor(process, Pid),
|
|
|
add_to_local_table(Name, Pid, Meta, Time, MRef, TableByName, TableByPid),
|
|
|
- do_rebuild_monitors(T, maps:put(Pid, MRef, NewMonitorRefs), State);
|
|
|
+ do_rebuild_monitors(T, maps:put(Pid, MRef, NewMRefs), TableByName, TableByPid);
|
|
|
|
|
|
{ok, MRef} ->
|
|
|
add_to_local_table(Name, Pid, Meta, Time, MRef, TableByName, TableByPid),
|
|
|
- do_rebuild_monitors(T, NewMonitorRefs, State)
|
|
|
+ do_rebuild_monitors(T, NewMRefs, TableByName, TableByPid)
|
|
|
end;
|
|
|
|
|
|
_ ->
|
|
|
- do_rebuild_monitors(T, NewMonitorRefs, State)
|
|
|
+ do_rebuild_monitors(T, NewMRefs, TableByName, TableByPid)
|
|
|
end.
|
|
|
|
|
|
-spec do_register_on_node(
|
|
@@ -480,17 +485,28 @@ update_local_table(Name, PreviousPid, {Pid, Meta, Time, MRef}, TableByName, Tabl
|
|
|
remove_from_local_table(Name, PreviousPid, TableByName, TableByPid),
|
|
|
add_to_local_table(Name, Pid, Meta, Time, MRef, TableByName, TableByPid).
|
|
|
|
|
|
+-spec purge_registry_for_remote_nodes(Scope :: atom(), TableByName :: atom(), TableByPid :: atom()) -> any().
|
|
|
+purge_registry_for_remote_nodes(Scope, TableByName, TableByPid) ->
|
|
|
+ LocalNode = node(),
|
|
|
+ RemoteNodesWithDoubles = ets:select(TableByName, [{
|
|
|
+ {'_', '_', '_', '_', '_', '$6'},
|
|
|
+ [{'=/=', '$6', LocalNode}],
|
|
|
+ ['$6']
|
|
|
+ }]),
|
|
|
+ RemoteNodes = ordsets:from_list(RemoteNodesWithDoubles),
|
|
|
+ ordsets:fold(fun(RemoteNode, _) ->
|
|
|
+ purge_registry_for_remote_node(Scope, RemoteNode, TableByName, TableByPid)
|
|
|
+ end, undefined, RemoteNodes).
|
|
|
+
|
|
|
-spec purge_registry_for_remote_node(Scope :: atom(), Node :: atom(), TableByName :: atom(), TableByPid :: atom()) -> true.
|
|
|
purge_registry_for_remote_node(Scope, Node, TableByName, TableByPid) when Node =/= node() ->
|
|
|
- %% loop elements for callback in a separate process to free scope process
|
|
|
+ %% loop elements for callback
|
|
|
RegistryTuples = get_registry_tuples_for_node(Node, TableByName),
|
|
|
- spawn(fun() ->
|
|
|
- lists:foreach(fun({Name, Pid, Meta, _Time}) ->
|
|
|
- syn_event_handler:call_event_handler(on_process_unregistered,
|
|
|
- [Scope, Name, Pid, Meta, {syn_remote_scope_node_down, Scope, Node}]
|
|
|
- )
|
|
|
- end, RegistryTuples)
|
|
|
- end),
|
|
|
+ lists:foreach(fun({Name, Pid, Meta, _Time}) ->
|
|
|
+ syn_event_handler:call_event_handler(on_process_unregistered,
|
|
|
+ [Scope, Name, Pid, Meta, {syn_remote_scope_node_down, Scope, Node}]
|
|
|
+ )
|
|
|
+ end, RegistryTuples),
|
|
|
%% remove all from pid table
|
|
|
true = ets:match_delete(TableByName, {'_', '_', '_', '_', '_', Node}),
|
|
|
true = ets:match_delete(TableByPid, {'_', '_', '_', '_', '_', Node}).
|