Browse Source

Add publish_to_local.

[ostinelli/syn#17]
Roberto Ostinelli 8 years ago
parent
commit
01e4ffa522
3 changed files with 64 additions and 2 deletions
  1. 5 0
      src/syn.erl
  2. 10 0
      src/syn_groups.erl
  3. 49 2
      test/syn_groups_SUITE.erl

+ 5 - 0
src/syn.erl

@@ -49,6 +49,7 @@
 -export([get_members/1, get_members/2]).
 -export([get_local_members/1, get_local_members/2]).
 -export([publish/2]).
+-export([publish_to_local/2]).
 -export([multi_call/2, multi_call/3]).
 -export([multi_call_reply/2]).
 
@@ -167,6 +168,10 @@ get_local_members(Name, with_meta) ->
 publish(Name, Message) ->
     syn_groups:publish(Name, Message).
 
+-spec publish_to_local(Name :: any(), Message :: any()) -> {ok, RecipientCount :: non_neg_integer()}.
+publish_to_local(Name, Message) ->
+    syn_groups:publish_to_local(Name, Message).
+
 -spec multi_call(Name :: any(), Message :: any()) ->
     {[{pid(), Reply :: any()}], [BadPid :: pid()]}.
 multi_call(Name, Message) ->

+ 10 - 0
src/syn_groups.erl

@@ -34,6 +34,7 @@
 -export([get_members/1, get_members/2]).
 -export([get_local_members/1, get_local_members/2]).
 -export([publish/2]).
+-export([publish_to_local/2]).
 -export([multi_call/2, multi_call/3]).
 -export([multi_call_reply/2]).
 
@@ -107,6 +108,15 @@ publish(Name, Message) ->
     lists:foreach(FSend, MemberPids),
     {ok, length(MemberPids)}.
 
+-spec publish_to_local(Name :: any(), Message :: any()) -> {ok, RecipientCount :: non_neg_integer()}.
+publish_to_local(Name, Message) ->
+    MemberPids = i_get_local_members(Name),
+    FSend = fun(Pid) ->
+        Pid ! Message
+    end,
+    lists:foreach(FSend, MemberPids),
+    {ok, length(MemberPids)}.
+
 -spec multi_call(Name :: any(), Message :: any()) -> {[{pid(), Reply :: any()}], [BadPid :: pid()]}.
 multi_call(Name, Message) ->
     multi_call(Name, Message, ?DEFAULT_MULTI_CALL_TIMEOUT_MS).

+ 49 - 2
test/syn_groups_SUITE.erl

@@ -47,7 +47,8 @@
     two_nodes_kill/1,
     two_nodes_publish/1,
     two_nodes_multi_call/1,
-    two_nodes_local_members/1
+    two_nodes_local_members/1,
+    two_nodes_local_publish/1
 ]).
 
 %% internals
@@ -105,7 +106,8 @@ groups() ->
             two_nodes_kill,
             two_nodes_publish,
             two_nodes_multi_call,
-            two_nodes_local_members
+            two_nodes_local_members,
+            two_nodes_local_publish
         ]}
     ].
 %% -------------------------------------------------------------------
@@ -591,6 +593,51 @@ two_nodes_local_members(Config) ->
     syn_test_suite_helper:kill_process(PidLocal2),
     syn_test_suite_helper:kill_process(PidSlave).
 
+two_nodes_local_publish(Config) ->
+    %% get slave
+    SlaveNode = proplists:get_value(slave_node, Config),
+    %% set schema location
+    application:set_env(mnesia, schema_location, ram),
+    rpc:call(SlaveNode, mnesia, schema_location, [ram]),
+    %% start
+    ok = syn:start(),
+    ok = syn:init(),
+    ok = rpc:call(SlaveNode, syn, start, []),
+    ok = rpc:call(SlaveNode, syn, init, []),
+    timer:sleep(100),
+    %% start processes
+    ResultPid = self(),
+    F = fun() -> recipient_loop(ResultPid) end,
+    PidLocal1 = syn_test_suite_helper:start_process(F),
+    PidLocal2 = syn_test_suite_helper:start_process(F),
+    PidSlave = syn_test_suite_helper:start_process(SlaveNode, F),
+    %% join
+    ok = syn:join(<<"my group">>, PidLocal1, {meta, pid_local_1}),
+    ok = syn:join(<<"my group">>, PidLocal2, {meta, pid_local_2}),
+    ok = syn:join(<<"my group">>, PidSlave, {meta, pid_slave}),
+    %% publish
+    syn:publish_to_local(<<"my group">>, {test, message}),
+    %% check publish was received by local pids
+    receive
+        {received, PidLocal1, {test, message}} -> ok
+    after 2000 ->
+        ok = published_message_was_not_received_by_pid_local_1
+    end,
+    receive
+        {received, PidLocal2, {test, message}} -> ok
+    after 2000 ->
+        ok = published_message_was_not_received_by_pid_local_2
+    end,
+    receive
+        {received, PidSlave, {test, message}} ->
+            ko = published_message_was_received_by_pid_slave
+    after 1000 ->
+        ok
+    end,
+    %% kill processes
+    syn_test_suite_helper:kill_process(PidLocal1),
+    syn_test_suite_helper:kill_process(PidLocal2),
+    syn_test_suite_helper:kill_process(PidSlave).
 
 %% ===================================================================
 %% Internal