From 360756d6303ad6e17498e7e08c54c85f32a9b668 Mon Sep 17 00:00:00 2001
From: Igor Zolotarev <yngvar.antonsson@gmail.com>
Date: Thu, 30 Jan 2025 02:25:06 +0300
Subject: [PATCH] Another try

---
 membership.lua         | 14 ++++++++++++++
 membership/members.lua |  8 ++++++++
 membership/stash.lua   |  2 ++
 3 files changed, 24 insertions(+)

diff --git a/membership.lua b/membership.lua
index 9b31d9b..eca72dd 100755
--- a/membership.lua
+++ b/membership.lua
@@ -37,12 +37,14 @@ local _sync_trigger = stash.get('_sync_trigger') or fiber.cond()
 local _ack_trigger = stash.get('_ack_trigger') or fiber.cond()
 local _ack_cache = stash.get('_ack_cache') or {}
 local _resolve_cache = stash.get('_resolve_cache') or {}
+local _allowed_uri_set = stash.get('_allowed_uri_set')
 
 local function after_reload()
     stash.set('_ack_cache', _ack_cache)
     stash.set('_ack_trigger', _ack_trigger)
     stash.set('_sync_trigger', _sync_trigger)
     stash.set('_resolve_cache', _resolve_cache)
+    stash.set('_allowed_uri_set', _allowed_uri_set)
 end
 
 local _sock = stash.get('_sock')
@@ -1004,6 +1006,17 @@ local function remove_member(uri)
     members.remove(uri)
 end
 
+--- Filter out members from the list.
+-- @function set_allowed_members
+-- @tparam uris table URIs to leave in the list
+local function set_allowed_members(uris)
+    checks('table')
+    table.clear(_allowed_uri_set)
+    for _, uri in ipairs(uris) do
+        _allowed_uri_set[uri] = true
+    end
+end
+
 do -- finish module loading
     opts.after_reload()
     events.after_reload()
@@ -1027,6 +1040,7 @@ return {
     get_member = get_member,
     remove_member = remove_member,
     set_payload = set_payload,
+    set_allowed_members = set_allowed_members,
 
 --- Encryption Functions.
 -- The encryption is handled by the
diff --git a/membership/members.lua b/membership/members.lua
index 2234723..f5bd752 100644
--- a/membership/members.lua
+++ b/membership/members.lua
@@ -18,6 +18,8 @@ local _all_members = table.copy(stash.get('members._all_members')) or {
     -- uri is a string in format '<host>:<port>'
 }
 
+local _allowed_uri_set = stash.get('_allowed_uri_set')
+
 function members.after_reload()
     stash.set('members._all_members', _all_members)
 end
@@ -88,6 +90,12 @@ function members.set(uri, status, incarnation, params)
     checks('string', 'number', 'number', { payload = '?table', clock_delta = '?number' })
 
     local member = _all_members[uri]
+
+    if not _allowed_uri_set[uri] and (status == opts.LEFT or status == opts.DEAD) then
+        opts.log_debug('Ignoring member %s with status %s', uri, opts.STATUS_NAMES[status])
+        return
+    end
+
     if member and incarnation < member.incarnation then
         error('Can not downgrade incarnation')
     end
diff --git a/membership/stash.lua b/membership/stash.lua
index d616291..07fd906 100644
--- a/membership/stash.lua
+++ b/membership/stash.lua
@@ -1,5 +1,7 @@
 local S = rawget(_G, '__membership_stash') or {}
 
+S['_allowed_uri_set'] = S['_allowed_uri_set'] or {}
+
 local log = require('log')
 
 local function f_body(fn_name, ...)