Browse Source

Allow a process to join a group multiple times.

Roberto Ostinelli 9 years ago
parent
commit
8c6408ed67
3 changed files with 35 additions and 18 deletions
  1. 1 2
      README.md
  2. 10 15
      src/syn_groups.erl
  3. 24 1
      test/syn_groups_SUITE.erl

+ 1 - 2
README.md

@@ -221,12 +221,11 @@ Types:
 To add a process to a group:
 
 ```erlang
-syn:join(Name, Pid) -> ok | {error, Error}.
+syn:join(Name, Pid) -> ok.
 
 Types:
 	Name = any()
 	Pid = pid()
-	Error = pid_already_in_group
 ```
 
 > When a process joins a group, Syn will automatically monitor it.

+ 10 - 15
src/syn_groups.erl

@@ -137,21 +137,16 @@ init([]) ->
     {stop, Reason :: any(), #state{}}.
 
 handle_call({join, Name, Pid}, _From, State) ->
-    case i_member(Pid, Name) of
-        false ->
-            %% add to table
-            mnesia:dirty_write(#syn_groups_table{
-                name = Name,
-                pid = Pid,
-                node = node()
-            }),
-            %% link
-            erlang:link(Pid),
-            %% return
-            {reply, ok, State};
-        _ ->
-            {reply, pid_already_in_group, State}
-    end;
+    %% add to group
+    mnesia:dirty_write(#syn_groups_table{
+        name = Name,
+        pid = Pid,
+        node = node()
+    }),
+    %% link
+    erlang:link(Pid),
+    %% return
+    {reply, ok, State};
 
 handle_call({leave, Name, Pid}, _From, State) ->
     case find_by_pid_and_name(Pid, Name) of

+ 24 - 1
test/syn_groups_SUITE.erl

@@ -33,6 +33,7 @@
 
 %% tests
 -export([
+    single_node_join/1,
     single_node_leave/1,
     single_node_kill/1,
     single_node_publish/1,
@@ -85,6 +86,7 @@ all() ->
 groups() ->
     [
         {single_node_process_groups, [shuffle], [
+            single_node_join,
             single_node_leave,
             single_node_kill,
             single_node_publish,
@@ -175,6 +177,27 @@ end_per_testcase(_TestCase, Config) ->
 %% ===================================================================
 %% Tests
 %% ===================================================================
+single_node_join(_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">>),
+    false = syn:member(Pid, <<"my group">>),
+    %% join
+    ok = syn:join(<<"my group">>, Pid),
+    %% allow to rejoin
+    ok = syn:join(<<"my group">>, Pid),
+    %% retrieve
+    [Pid] = syn:get_members(<<"my group">>),
+    true = syn:member(Pid, <<"my group">>),
+    %% kill process
+    syn_test_suite_helper:kill_process(Pid).
+
 single_node_leave(_Config) ->
     %% set schema location
     application:set_env(mnesia, schema_location, ram),
@@ -303,7 +326,7 @@ single_node_multi_call_when_recipient_crashes(_Config) ->
     %% call
     {Time, {Replies, BadPids}} = timer:tc(syn, multi_call, [<<"my group">>, get_pid_name]),
     %% check that pid2 was monitored, no need to wait for timeout
-    true = Time/1000 < 1000,
+    true = Time / 1000 < 1000,
     %% check responses
     2 = length(Replies),
     pid1 = proplists:get_value(Pid1, Replies),