Skip to content

Commit bce56e7

Browse files
authored
Merge pull request #83 from urmastalimaa/fix_already_started_when_registered_process_restarted
Verify that the process is alive in lookup/2
2 parents 8173c5e + a3f5c66 commit bce56e7

2 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/syn_registry.erl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,20 @@ lookup(Scope, Name) ->
7878
TableByName ->
7979
case find_registry_entry_by_name(Name, TableByName) of
8080
undefined -> undefined;
81-
{Name, Pid, Meta, _, _, _} -> {Pid, Meta}
81+
{Name, Pid, Meta, _, _, Node} ->
82+
% This read can be initiated prior to registration, by a
83+
% supervisor or supervisor-like process trying to restart a
84+
% stopped process in response to a 'DOWN', while the 'DOWN'
85+
% handler in this module is yet to update TableByName.
86+
%
87+
% Verifying aliveness avoids confusing already_started
88+
% errors while restarting registered processes.
89+
% The aliveness check is only necessary when the Pid is
90+
% local.
91+
case Node =:= node() andalso not is_process_alive(Pid) of
92+
true -> undefined;
93+
false -> {Pid, Meta}
94+
end
8295
end
8396
end.
8497

test/syn_registry_SUITE.erl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
-export([
3636
one_node_via_register_unregister/1,
3737
one_node_via_register_unregister_with_metadata/1,
38-
one_node_strict_mode/1
38+
one_node_strict_mode/1,
39+
one_node_repeated_restart/1
3940
]).
4041
-export([
4142
three_nodes_discover/1,
@@ -91,7 +92,8 @@ groups() ->
9192
{one_node_registry, [shuffle], [
9293
one_node_via_register_unregister,
9394
one_node_via_register_unregister_with_metadata,
94-
one_node_strict_mode
95+
one_node_strict_mode,
96+
one_node_repeated_restart
9597
]},
9698
{three_nodes_registry, [shuffle], [
9799
three_nodes_discover,
@@ -285,6 +287,21 @@ one_node_strict_mode(_Config) ->
285287
ok = syn:register(scope, "strict-true", Self),
286288
{Self, undefined} = syn:lookup(scope, "strict-true").
287289

290+
one_node_repeated_restart(_Config) ->
291+
%% start syn
292+
ok = syn:start(),
293+
syn:add_node_to_scopes([scope]),
294+
ViaTuple = {via, syn, {scope, <<"my proc">>, my_metadata}},
295+
% Data races between the 'DOWN' handler and reads pre-registration reads
296+
% cause intermittent failures. Repeat count 100 is heuristically chosen as
297+
% it consistently surfaced the problem at the time of writing.
298+
RepeatCount = 100,
299+
StartStop = fun(_) ->
300+
{ok, Pid} = syn_test_gen_server:start_link(ViaTuple),
301+
gen_server:stop(Pid)
302+
end,
303+
lists:foreach(StartStop, lists:duplicate(RepeatCount, 0)).
304+
288305
three_nodes_discover(Config) ->
289306
%% get slaves
290307
SlaveNode1 = proplists:get_value(syn_slave_1, Config),

0 commit comments

Comments
 (0)