File 2618-pg-to-remove-a-group-from-nodes-when-the-group-is-em.patch of Package erlang

From a94f58b9aeb9072e6167859286903706a53f0915 Mon Sep 17 00:00:00 2001
From: Jechol Lee <mr.jechol@gmail.com>
Date: Thu, 12 Nov 2020 13:40:00 +0900
Subject: [PATCH] pg to remove a group from nodes when the group is empty

---
 lib/kernel/src/pg.erl        |  4 ++--
 lib/kernel/test/pg_SUITE.erl | 27 ++++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/lib/kernel/src/pg.erl b/lib/kernel/src/pg.erl
index 580759a9bf..37265a5db0 100644
--- a/lib/kernel/src/pg.erl
+++ b/lib/kernel/src/pg.erl
@@ -285,9 +285,9 @@ handle_info({leave, Peer, PidOrPids, Groups}, #state{scope = Scope, nodes = Node
                 fun (Group, Acc) ->
                     case maps:get(Group, Acc) of
                         PidOrPids ->
-                            Acc;
+                            maps:remove(Group, Acc);
                         [PidOrPids] ->
-                            Acc;
+                            maps:remove(Group, Acc);
                         Existing when is_pid(PidOrPids) ->
                             Acc#{Group => lists:delete(PidOrPids, Existing)};
                         Existing ->
diff --git a/lib/kernel/test/pg_SUITE.erl b/lib/kernel/test/pg_SUITE.erl
index 725169cda5..f03b8a6a39 100644
--- a/lib/kernel/test/pg_SUITE.erl
+++ b/lib/kernel/test/pg_SUITE.erl
@@ -43,6 +43,7 @@
     overlay_missing/0, overlay_missing/1,
     single/0, single/1,
     two/1,
+    empty_group_by_remote_leave/0, empty_group_by_remote_leave/1,
     thundering_herd/0, thundering_herd/1,
     initial/1,
     netsplit/1,
@@ -101,7 +102,7 @@ groups() ->
         {basic, [parallel], [errors, pg, leave_exit_race, single, overlay_missing]},
         {performance, [sequential], [thundering_herd]},
         {cluster, [parallel], [process_owner_check, two, initial, netsplit, trisplit, foursplit,
-            exchange, nolocal, double, scope_restart, missing_scope_join,
+            exchange, nolocal, double, scope_restart, missing_scope_join, empty_group_by_remote_leave,
             disconnected_start, forced_sync, group_leave]}
     ].
 
@@ -270,7 +271,31 @@ two(Config) when is_list(Config) ->
     stop_node(TwoPeer, Socket),
     %% hope that 'nodedown' comes before we route our request
     sync(?FUNCTION_NAME),
+    ok.
+
+empty_group_by_remote_leave() ->
+    [{doc, "Empty group should be deleted from nodes."}].
+
+empty_group_by_remote_leave(Config) when is_list(Config) ->
+    {TwoPeer, Socket} = spawn_node(?FUNCTION_NAME, ?FUNCTION_NAME),
+    RemoteNode = rpc:call(TwoPeer, erlang, whereis, [?FUNCTION_NAME]),
+    RemotePid = erlang:spawn(TwoPeer, forever()),
+    % remote join
+    ?assertEqual(ok, rpc:call(TwoPeer, pg, join, [?FUNCTION_NAME, ?FUNCTION_NAME, RemotePid])),
+    sync({?FUNCTION_NAME, TwoPeer}),
+    ?assertEqual([RemotePid], pg:get_members(?FUNCTION_NAME, ?FUNCTION_NAME)),
+    % inspecting internal state is not best practice, but there's no other way to check if the state is correct.
+    {state, _, _, #{RemoteNode := {_, RemoteMap}}} = sys:get_state(?FUNCTION_NAME),
+    ?assertEqual(#{?FUNCTION_NAME => [RemotePid]}, RemoteMap),
+    % remote leave
+    ?assertEqual(ok, rpc:call(TwoPeer, pg, leave, [?FUNCTION_NAME, ?FUNCTION_NAME, RemotePid])),
+    sync({?FUNCTION_NAME, TwoPeer}),
     ?assertEqual([], pg:get_members(?FUNCTION_NAME, ?FUNCTION_NAME)),
+    {state, _, _, #{RemoteNode := {_, NewRemoteMap}}} = sys:get_state(?FUNCTION_NAME),
+    % empty group should be deleted.
+    ?assertEqual(#{}, NewRemoteMap),
+
+    stop_node(TwoPeer, Socket),
     ok.
 
 thundering_herd() ->
-- 
2.26.2

openSUSE Build Service is sponsored by