Browse Source

Trap errors in update functions.

Roberto Ostinelli 3 years ago
parent
commit
1cc8df2427
4 changed files with 45 additions and 19 deletions
  1. 11 2
      src/syn_pg.erl
  2. 11 2
      src/syn_registry.erl
  3. 1 0
      test/syn_pg_SUITE.erl
  4. 22 15
      test/syn_registry_SUITE.erl

+ 11 - 2
src/syn_pg.erl

@@ -324,8 +324,17 @@ handle_call({'3.0', join_or_update_on_node, RequesterNode, GroupName, Pid, MetaO
 
                 {{_, _}, TableMeta, _, MRef, _} when is_function(MetaOrFun) ->
                     %% update with fun
-                    Meta = MetaOrFun(TableMeta),
-                    do_join_on_node(GroupName, Pid, Meta, MRef, normal, RequesterNode, on_group_process_updated, State);
+                    try MetaOrFun(TableMeta) of
+                        Meta ->
+                            do_join_on_node(GroupName, Pid, Meta, MRef, normal, RequesterNode, on_group_process_updated, State)
+
+                    catch Class:Reason:Stacktrace ->
+                        error_logger:error_msg(
+                            "SYN[~s] Error ~p:~p in pg update function: ~p",
+                            [node(), Class, Reason, Stacktrace]
+                        ),
+                        {reply, {{error, {update_fun, {Reason, Stacktrace}}}, undefined}, State}
+                    end;
 
                 {{_, _}, MetaOrFun, _, _, _} ->
                     %% re-joined with same meta

+ 11 - 2
src/syn_registry.erl

@@ -234,8 +234,17 @@ handle_call({'3.0', register_or_update_on_node, RequesterNode, Name, Pid, MetaOr
 
                 {Name, Pid, TableMeta, _, MRef, _} when is_function(MetaOrFun) ->
                     %% update with fun
-                    Meta = MetaOrFun(Pid, TableMeta),
-                    do_register_on_node(Name, Pid, Meta, MRef, normal, RequesterNode, on_registry_process_updated, State);
+                    try MetaOrFun(Pid, TableMeta) of
+                        Meta ->
+                            do_register_on_node(Name, Pid, Meta, MRef, normal, RequesterNode, on_registry_process_updated, State)
+
+                    catch Class:Reason:Stacktrace ->
+                        error_logger:error_msg(
+                            "SYN[~s] Error ~p:~p in registry update function: ~p",
+                            [node(), Class, Reason, Stacktrace]
+                        ),
+                        {reply, {{error, {update_fun, {Reason, Stacktrace}}}, undefined}, State}
+                    end;
 
                 {Name, Pid, MetaOrFun, _, _, _} ->
                     %% same pid, same meta

+ 1 - 0
test/syn_pg_SUITE.erl

@@ -1688,6 +1688,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),
 
     %% update
     {ok, {Pid, {recipient, TestPid, 20}}} = syn:update_member(scope_all, "my-group", Pid, fun({recipient, TestPid0, Count}) ->

+ 22 - 15
test/syn_registry_SUITE.erl

@@ -1489,17 +1489,28 @@ three_nodes_update(Config) ->
 
     %% errors
     {error, undefined} = syn:update_registry(scope_all, "unknown", fun(_IPid, ExistingMeta) -> ExistingMeta end),
+    {error, {update_fun, {badarith, _}}} = syn:update_registry(scope_all, "my-proc", fun(_IPid, _IMeta) -> 1/0 end),
 
-    %% update
-    {ok, {Pid, {recipient, TestPid, 20}}} = syn:update_registry(
-        scope_all,
-        "my-proc",
-        fun(IPid, {recipient, TestPid0, Count}) ->
-            IPid = Pid,
-            {recipient, TestPid0, Count * 2}
-        end
+    %% retrieve
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 10}},
+        fun() -> syn:lookup(scope_all, "my-proc") end
+    ),
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 10}},
+        fun() -> rpc:call(SlaveNode1, syn, lookup, [scope_all, "my-proc"]) end
+    ),
+    syn_test_suite_helper:assert_wait(
+        {Pid, {recipient, TestPid, 10}},
+        fun() -> rpc:call(SlaveNode2, syn, lookup, [scope_all, "my-proc"]) end
     ),
 
+    %% update
+    {ok, {Pid, {recipient, TestPid, 20}}} = syn:update_registry(scope_all, "my-proc", fun(IPid, {recipient, TestPid0, Count}) ->
+        IPid = Pid,
+        {recipient, TestPid0, Count * 2}
+    end),
+
     %% retrieve
     syn_test_suite_helper:assert_wait(
         {Pid, {recipient, TestPid, 20}},
@@ -1532,13 +1543,9 @@ three_nodes_update(Config) ->
     ]),
 
     %% update on remote
-    {ok, {PidOn1, {recipient, TestPid, 1001}}} = syn:update_registry(
-        scope_all,
-        "my-proc-on-1",
-        fun(_IPid, {recipient, TestPid0, Count}) ->
-            {recipient, TestPid0, Count + 1}
-        end
-    ),
+    {ok, {PidOn1, {recipient, TestPid, 1001}}} = syn:update_registry(scope_all, "my-proc-on-1", fun(_IPid, {recipient, TestPid0, Count}) ->
+        {recipient, TestPid0, Count + 1}
+    end),
 
     %% retrieve
     syn_test_suite_helper:assert_wait(