Browse Source

Merge pull request #26 from seb3s/seb3s-fix-issue-24

Fix syn groups leaving bug
Roberto Ostinelli 8 years ago
parent
commit
fc3d36e6b8
2 changed files with 45 additions and 3 deletions
  1. 5 2
      src/syn_groups.erl
  2. 40 1
      test/syn_groups_SUITE.erl

+ 5 - 2
src/syn_groups.erl

@@ -184,8 +184,11 @@ handle_call({leave, Name, Pid}, _From, State) ->
         Process ->
         Process ->
             %% remove from table
             %% remove from table
             remove_process(Process),
             remove_process(Process),
-            %% unlink
-            erlang:unlink(Pid),
+            %% unlink only when process is no more in groups
+            case find_groups_by_pid(Pid) of
+                [] -> erlang:unlink(Pid);
+                _ -> nop
+            end,
             %% reply
             %% reply
             {reply, ok, State}
             {reply, ok, State}
     end;
     end;

+ 40 - 1
test/syn_groups_SUITE.erl

@@ -36,6 +36,7 @@
     single_node_join/1,
     single_node_join/1,
     single_node_leave/1,
     single_node_leave/1,
     single_node_kill/1,
     single_node_kill/1,
+    single_node_leave_and_kill_multi_groups/1,
     single_node_publish/1,
     single_node_publish/1,
     single_node_multi_call/1,
     single_node_multi_call/1,
     single_node_multi_call_when_recipient_crashes/1,
     single_node_multi_call_when_recipient_crashes/1,
@@ -92,6 +93,7 @@ groups() ->
             single_node_join,
             single_node_join,
             single_node_leave,
             single_node_leave,
             single_node_kill,
             single_node_kill,
+            single_node_leave_and_kill_multi_groups,
             single_node_publish,
             single_node_publish,
             single_node_multi_call,
             single_node_multi_call,
             single_node_multi_call_when_recipient_crashes,
             single_node_multi_call_when_recipient_crashes,
@@ -259,6 +261,43 @@ single_node_kill(_Config) ->
     false = syn:member(Pid, <<"my group 1">>),
     false = syn:member(Pid, <<"my group 1">>),
     false = syn:member(Pid, <<"my group 2">>).
     false = syn:member(Pid, <<"my group 2">>).
 
 
+single_node_leave_and_kill_multi_groups(_Config) ->
+    %% set schema location
+    application:set_env(mnesia, schema_location, ram),
+    %% start
+    ok = syn:start(),
+    ok = syn:init(),
+    %% start process
+    Pid = syn_test_suite_helper:start_process(),
+    %% retrieve
+    [] = syn:get_members(<<"my group 1">>),
+    [] = syn:get_members(<<"my group 2">>),
+    false = syn:member(Pid, <<"my group 1">>),
+    false = syn:member(Pid, <<"my group 2">>),
+    %% join
+    ok = syn:join(<<"my group 1">>, Pid),
+    ok = syn:join(<<"my group 2">>, Pid),
+    %% retrieve
+    [Pid] = syn:get_members(<<"my group 1">>),
+    [Pid] = syn:get_members(<<"my group 2">>),
+    true = syn:member(Pid, <<"my group 1">>),
+    true = syn:member(Pid, <<"my group 2">>),
+    %% leave group 1
+    ok = syn:leave(<<"my group 1">>, Pid),
+    %% retrieve
+    [] = syn:get_members(<<"my group 1">>),
+    [Pid] = syn:get_members(<<"my group 2">>),
+    false = syn:member(Pid, <<"my group 1">>),
+    true = syn:member(Pid, <<"my group 2">>),
+    %% kill process
+    syn_test_suite_helper:kill_process(Pid),
+    timer:sleep(100),
+    %% retrieve
+    [] = syn:get_members(<<"my group 1">>),
+    [] = syn:get_members(<<"my group 2">>),
+    false = syn:member(Pid, <<"my group 1">>),
+    false = syn:member(Pid, <<"my group 2">>).
+
 single_node_publish(_Config) ->
 single_node_publish(_Config) ->
     %% set schema location
     %% set schema location
     application:set_env(mnesia, schema_location, ram),
     application:set_env(mnesia, schema_location, ram),
@@ -532,4 +571,4 @@ called_loop_that_crashes(_PidName) ->
     end.
     end.
 
 
 process_groups_process_exit_callback_dummy(Name, Pid, Meta, Reason) ->
 process_groups_process_exit_callback_dummy(Name, Pid, Meta, Reason) ->
-    global:send(syn_process_groups_SUITE_result, {exited, node(), Name, Pid, Meta, Reason}).
+    global:send(syn_process_groups_SUITE_result, {exited, node(), Name, Pid, Meta, Reason}).