Skip to content
Snippets Groups Projects
Commit 196e647e authored by Mergen Imeev's avatar Mergen Imeev Committed by Alexander Turenko
Browse files

experimental: introduce filter()

This patch introduces the filter() function in the experimental.connpool
module. The function takes options containing some constraints as the
only argument and returns an array of instance names that satisfy those
constraints.

Part of #9842

NO_DOC=will be added later
parent 60b6a1f6
No related branches found
No related tags found
No related merge requests found
......@@ -2,3 +2,5 @@
* Introduced the `experimental.connpool` module and the
`connect()` function of this module (gh-9842).
* Introduced the `filter()` function in the `experimental.connpool`
module (gh-9842).
......@@ -55,6 +55,64 @@ local function connect(instance_name, opts)
return conn
end
local function is_roles_match(expected_roles, present_roles)
if expected_roles == nil or next(expected_roles) == nil then
return true
end
if present_roles == nil or next(present_roles) == nil then
return false
end
local roles = {}
for _, present_role_name in pairs(present_roles) do
roles[present_role_name] = true
end
for _, expected_role_name in pairs(expected_roles) do
if roles[expected_role_name] == nil then
return false
end
end
return true
end
local function is_labels_match(expected_labels, present_labels)
if expected_labels == nil or next(expected_labels) == nil then
return true
end
if present_labels == nil or next(present_labels) == nil then
return false
end
for label, value in pairs(expected_labels) do
if present_labels[label] ~= value then
return false
end
end
return true
end
local function is_candidate_match(instance_name, opts)
assert(opts ~= nil and type(opts) == 'table')
local get_opts = {instance = instance_name}
return is_roles_match(opts.roles, config:get('roles', get_opts)) and
is_labels_match(opts.labels, config:get('labels', get_opts))
end
local function filter(opts)
checks({
labels = '?table',
roles = '?table',
})
local candidates = {}
for instance_name in pairs(config:instances()) do
if is_candidate_match(instance_name, opts or {}) then
table.insert(candidates, instance_name)
end
end
return candidates
end
return {
connect = connect,
filter = filter,
}
......@@ -97,3 +97,110 @@ g.test_connect = function(g)
g.server_3:exec(check_conn)
g.server_4:exec(check_conn)
end
g.test_filter = function(g)
local dir = treegen.prepare_directory(g, {}, {})
local config = [[
credentials:
users:
guest:
roles: [super]
iproto:
listen:
- uri: 'unix/:./{{ instance_name }}.iproto'
groups:
group-001:
replicasets:
replicaset-001:
instances:
instance-001:
database:
mode: rw
roles: [r1, r2]
labels:
l1: 'one'
l2: 'two'
instance-002:
labels:
l1: 'one'
replicaset-002:
instances:
instance-003:
database:
mode: rw
roles: [r1, r2]
instance-004:
labels:
l1: 'one_one'
l3: 'three'
roles: [r1]
]]
treegen.write_script(dir, 'config.yaml', config)
local role = string.dump(function()
return {
stop = function() end,
apply = function() end,
validate = function() end,
}
end)
treegen.write_script(dir, 'r1.lua', role)
treegen.write_script(dir, 'r2.lua', role)
local opts = {
env = {LUA_PATH = os.environ()['LUA_PATH']},
config_file = 'config.yaml',
chdir = dir,
}
g.server_1 = server:new(fun.chain(opts, {alias = 'instance-001'}):tomap())
g.server_2 = server:new(fun.chain(opts, {alias = 'instance-002'}):tomap())
g.server_3 = server:new(fun.chain(opts, {alias = 'instance-003'}):tomap())
g.server_4 = server:new(fun.chain(opts, {alias = 'instance-004'}):tomap())
g.server_1:start({wait_until_ready = false})
g.server_2:start({wait_until_ready = false})
g.server_3:start({wait_until_ready = false})
g.server_4:start({wait_until_ready = false})
g.server_1:wait_until_ready()
g.server_2:wait_until_ready()
g.server_3:wait_until_ready()
g.server_4:wait_until_ready()
local function check()
local connpool = require('experimental.connpool')
local exp = {"instance-001", "instance-004", "instance-003"}
local opts = {roles = {'r1'}}
t.assert_items_equals(connpool.filter(opts), exp)
exp = {"instance-001", "instance-003"}
opts = {roles = {'r1', 'r2'}}
t.assert_items_equals(connpool.filter(opts), exp)
exp = {"instance-001", "instance-002"}
opts = {labels = {l1 = 'one'}}
t.assert_items_equals(connpool.filter(opts), exp)
exp = {"instance-001"}
opts = {labels = {l1 = 'one', l2 = 'two'}}
t.assert_items_equals(connpool.filter(opts), exp)
exp = {"instance-004"}
opts = {labels = {l1 = 'one_one'}, roles = {'r1'}}
t.assert_items_equals(connpool.filter(opts), exp)
exp = {}
opts = {labels = {l1 = 'one_one', l2 = 'two'}, roles = {'r1'}}
t.assert_items_equals(connpool.filter(opts), exp)
exp = {"instance-001", "instance-002", "instance-003", "instance-004"}
t.assert_items_equals(connpool.filter(), exp)
end
g.server_1:exec(check)
g.server_2:exec(check)
g.server_3:exec(check)
g.server_4:exec(check)
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment