Browse Source

Do not trigger update callback if update fun does not change the value of meta.

Roberto Ostinelli 3 years ago
parent
commit
decb0a612f
4 changed files with 54 additions and 1 deletions
  1. 3 0
      src/syn_pg.erl
  2. 3 0
      src/syn_registry.erl
  3. 24 1
      test/syn_pg_SUITE.erl
  4. 24 0
      test/syn_registry_SUITE.erl

+ 3 - 0
src/syn_pg.erl

@@ -328,6 +328,9 @@ handle_call({'3.0', join_or_update_on_node, RequesterNode, GroupName, Pid, MetaO
                 {{_, _}, TableMeta, _, MRef, _} when is_function(MetaOrFun) ->
                     %% update with fun
                     try MetaOrFun(TableMeta) of
+                        Meta when Meta =:= TableMeta ->
+                            {reply, {noop, TableMeta}, State};
+
                         Meta ->
                             do_join_on_node(GroupName, Pid, Meta, MRef, normal, RequesterNode, on_group_process_updated, State)
 

+ 3 - 0
src/syn_registry.erl

@@ -238,6 +238,9 @@ handle_call({'3.0', register_or_update_on_node, RequesterNode, Name, Pid, MetaOr
                 {Name, Pid, TableMeta, _, MRef, _} when is_function(MetaOrFun) ->
                     %% update with fun
                     try MetaOrFun(Pid, TableMeta) of
+                        Meta when Meta =:= TableMeta ->
+                            {reply, {noop, TableMeta}, State};
+
                         Meta ->
                             do_register_on_node(Name, Pid, Meta, MRef, normal, RequesterNode, on_registry_process_updated, State)
 

+ 24 - 1
test/syn_pg_SUITE.erl

@@ -1692,7 +1692,7 @@ three_nodes_member_and_update(Config) ->
     {error, undefined} = syn:update_member(scope_all, "my-group", PidOn1, fun(ExistingMeta) -> ExistingMeta end),
     InvalidPid = list_to_pid("<0.9999.0>"),
     {error, not_alive} = syn:update_member(scope_all, "my-group", InvalidPid, fun(ExistingMeta) -> ExistingMeta end),
-    {error, {update_fun, {badarith, _}}} = syn:update_member(scope_all, "my-group", Pid, fun(_ExistingMeta) -> 1 / 0 end),
+    {error, {update_fun, {badarith, _}}} = syn:update_member(scope_all, "my-group", Pid, fun(_ExistingMeta) -> 1/0 end),
 
     %% update
     {ok, {Pid, {recipient, TestPid, 20}}} = syn:update_member(scope_all, "my-group", Pid, fun({recipient, TestPid0, Count}) ->
@@ -1720,6 +1720,29 @@ three_nodes_member_and_update(Config) ->
         {on_group_process_updated, SlaveNode2, scope_all, "my-group", Pid, 20, normal}
     ]),
 
+    %% update with same data
+    {ok, {Pid, {recipient, TestPid, 20}}} = syn:update_member(scope_all, "my-group", Pid, fun({recipient, TestPid0, Count}) ->
+        {recipient, TestPid0, Count}
+    end),
+
+    %% retrieve
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 20}},
+        fun() -> syn:member(scope_all, "my-group", Pid) end
+    ),
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 20}},
+        fun() -> rpc:call(SlaveNode1, syn, member, [scope_all, "my-group", Pid]) end
+    ),
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 20}},
+        fun() -> rpc:call(SlaveNode2, syn, member, [scope_all, "my-group", Pid]) end
+    ),
+
+    %% check no callbacks called
+    timer:sleep(100),
+    syn_test_suite_helper:assert_empty_queue(),
+
     %% join on remote
     ok = syn:join(scope_all, "my-group", PidOn1, {recipient, TestPid, 1000}),
 

+ 24 - 0
test/syn_registry_SUITE.erl

@@ -1581,6 +1581,30 @@ three_nodes_update(Config) ->
         {on_registry_process_updated, SlaveNode2, scope_all, "my-proc", Pid, 20, normal}
     ]),
 
+    %% update with same data
+    {ok, {Pid, {recipient, TestPid, 20}}} = syn:update_registry(scope_all, "my-proc", fun(IPid, {recipient, TestPid0, Count}) ->
+        IPid = Pid,
+        {recipient, TestPid0, Count}
+    end),
+
+    %% retrieve
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 20}},
+        fun() -> syn:lookup(scope_all, "my-proc") end
+    ),
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 20}},
+        fun() -> rpc:call(SlaveNode1, syn, lookup, [scope_all, "my-proc"]) end
+    ),
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 20}},
+        fun() -> rpc:call(SlaveNode2, syn, lookup, [scope_all, "my-proc"]) end
+    ),
+
+    %% check no callbacks called
+    timer:sleep(100),
+    syn_test_suite_helper:assert_empty_queue(),
+
     %% register on remote
     ok = syn:register(scope_all, "my-proc-on-1", PidOn1, {recipient, TestPid, 1000}),