From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 414002EC2F for ; Wed, 15 May 2019 15:36:52 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oSGy2P-jGnE3 for ; Wed, 15 May 2019 15:36:52 -0400 (EDT) Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id D37022EC70 for ; Wed, 15 May 2019 15:36:51 -0400 (EDT) From: Vladislav Shpilevoy Subject: [tarantool-patches] [PATCH 05/10] swim: Lua bindings to manipulate member table Date: Wed, 15 May 2019 22:36:42 +0300 Message-Id: <0310c1049d3d6d11c85c86de728b2ed825ba7f54.1557948687.git.v.shpilevoy@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Expose methods to add, remove, probe members by uri, uuid. Expose broadcast method to probe multiple members by port. Part of #3234 --- src/lua/swim.lua | 71 +++++++++++++++++ test/swim/swim.result | 171 ++++++++++++++++++++++++++++++++++++++++ test/swim/swim.test.lua | 60 ++++++++++++++ 3 files changed, 302 insertions(+) diff --git a/src/lua/swim.lua b/src/lua/swim.lua index bca98627c..c828faceb 100644 --- a/src/lua/swim.lua +++ b/src/lua/swim.lua @@ -272,6 +272,73 @@ local function swim_serialize(s) return s.cfg.index end +-- +-- Ping a member probably located at @a uri. +-- +local function swim_probe_member(s, uri) + local func_name = 'swim:probe_member' + local ptr = swim_check_instance(s, func_name) + uri = swim_check_uri(uri, func_name) + if capi.swim_probe_member(ptr, uri) ~= 0 then + return nil, box.error.last() + end + return true +end + +-- +-- Add a new member to the member table explicitly. +-- +local function swim_add_member(s, cfg) + local func_name = 'swim:add_member' + local ptr = swim_check_instance(s, func_name) + if type(cfg) ~= 'table' then + return error(func_name..': expected table member definition') + end + local uri = swim_check_uri(cfg.uri, func_name) + local uuid = swim_check_uuid(cfg.uuid, func_name) + if capi.swim_add_member(ptr, uri, uuid) ~= 0 then + return nil, box.error.last() + end + return true +end + +-- +-- Remove a member by @a uuid immediately from the local member +-- table. +-- +local function swim_remove_member(s, uuid) + local func_name = 'swim:remove_member' + local ptr = swim_check_instance(s, func_name) + uuid = swim_check_uuid(uuid, func_name) + if capi.swim_remove_member(ptr, uuid) ~= 0 then + return nil, box.error.last() + end + return true +end + +-- +-- Broadcast a ping message on all interfaces with @a port +-- destination. Port can be omitted, then currently bound is used. +-- +local function swim_broadcast(s, port) + local func_name = 'swim:broadcast' + local ptr = swim_check_instance(s, func_name) + if port == nil then + port = -1 + else + if type(port) == 'string' then + port = tonumber(port) + end + if type(port) ~= 'number' then + return error(func_name..': expected number port') + end + end + if capi.swim_broadcast(ptr, port) ~= 0 then + return nil, box.error.last() + end + return true +end + -- -- Normal metatable of a configured SWIM instance. -- @@ -281,6 +348,10 @@ local swim_mt = { quit = swim_quit, size = swim_size, is_configured = swim_is_configured, + probe_member = swim_probe_member, + add_member = swim_add_member, + remove_member = swim_remove_member, + broadcast = swim_broadcast, }, __serialize = swim_serialize } diff --git a/test/swim/swim.result b/test/swim/swim.result index 2e5025da6..0ab3dafe0 100644 --- a/test/swim/swim.result +++ b/test/swim/swim.result @@ -195,6 +195,177 @@ s.cfg() s:delete() --- ... +-- +-- Basic member table manipulations. +-- +s1 = swim.new({uuid = uuid(1), uri = uri(), heartbeat_rate = 0.01}) +--- +... +s2 = swim.new({uuid = uuid(2), uri = listen_uri, heartbeat_rate = 0.01}) +--- +... +s1.broadcast() +--- +- error: 'builtin/swim.lua:: swim:broadcast: first argument is not a SWIM instance' +... +s1:broadcast('wrong port') +--- +- error: 'swim:broadcast: expected number port' +... +-- Note, broadcast takes a port, not a URI. +s1:broadcast('127.0.0.1:3333') +--- +- error: 'swim:broadcast: expected number port' +... +-- Ok to broadcast on default port. +s1:broadcast() +--- +- true +... +s1:broadcast(listen_port) +--- +- true +... +while s2:size() ~= 2 do fiber.sleep(0.01) end +--- +... +s1:size() +--- +- 2 +... +s2:size() +--- +- 2 +... +s1.remove_member() +--- +- error: 'builtin/swim.lua:: swim:remove_member: first argument is not a SWIM instance' +... +s1:remove_member(100) +--- +- error: 'builtin/swim.lua:: swim:remove_member: expected string UUID' +... +s1:remove_member('1234') +--- +- error: 'builtin/swim.lua:: swim:remove_member: invalid UUID' +... +s1:remove_member(uuid(2)) +--- +- true +... +s1:size() +--- +- 1 +... +s1.add_member() +--- +- error: 'builtin/swim.lua:: swim:add_member: first argument is not a SWIM instance' +... +s1:add_member(100) +--- +- error: 'swim:add_member: expected table member definition' +... +s1:add_member({uri = true}) +--- +- error: 'builtin/swim.lua:: swim:add_member: expected string URI or port number' +... +s1:add_member({uri = listen_uri}) +--- +- null +- 'swim.add_member: URI and UUID are mandatory' +... +s1:add_member({uuid = uuid(2)}) +--- +- null +- 'swim.add_member: URI and UUID are mandatory' +... +s1:add_member({uri = listen_uri, uuid = uuid(2)}) +--- +- true +... +s1:add_member({uri = listen_uri, uuid = uuid(2)}) +--- +- null +- 'swim.add_member: a member with such UUID already exists' +... +s1:size() +--- +- 2 +... +s1:cfg({uuid = uuid(3)}) +--- +- true +... +-- Can't remove self. +s1:remove_member(uuid(3)) +--- +- null +- 'swim.remove_member: can not remove self' +... +-- Not existing. +s1:remove_member(uuid(4)) +--- +- true +... +-- Old self. +s1:remove_member(uuid(1)) +--- +- true +... +s1:delete() +--- +... +s2:delete() +--- +... +s1 = swim.new({uuid = uuid(1), uri = uri()}) +--- +... +s2 = swim.new({uuid = uuid(2), uri = listen_uri}) +--- +... +s1.probe_member() +--- +- error: 'builtin/swim.lua:: swim:probe_member: first argument is not a SWIM instance' +... +s1:probe_member() +--- +- null +- 'swim.probe_member: URI is mandatory' +... +s1:probe_member(true) +--- +- error: 'builtin/swim.lua:: swim:probe_member: expected string URI or port number' +... +-- Not existing URI is ok - nothing happens. +s1:probe_member('127.0.0.1:1') +--- +- true +... +fiber.yield() +--- +... +s1:size() +--- +- 1 +... +s1:probe_member(listen_uri) +--- +- true +... +while s1:size() ~= 2 do fiber.sleep(0.01) end +--- +... +s2:size() +--- +- 2 +... +s1:delete() +--- +... +s2:delete() +--- +... test_run:cmd("clear filter") --- - true diff --git a/test/swim/swim.test.lua b/test/swim/swim.test.lua index 719783133..1e55a828a 100644 --- a/test/swim/swim.test.lua +++ b/test/swim/swim.test.lua @@ -65,4 +65,64 @@ s.is_configured() s.cfg() s:delete() +-- +-- Basic member table manipulations. +-- +s1 = swim.new({uuid = uuid(1), uri = uri(), heartbeat_rate = 0.01}) +s2 = swim.new({uuid = uuid(2), uri = listen_uri, heartbeat_rate = 0.01}) + +s1.broadcast() +s1:broadcast('wrong port') +-- Note, broadcast takes a port, not a URI. +s1:broadcast('127.0.0.1:3333') +-- Ok to broadcast on default port. +s1:broadcast() + +s1:broadcast(listen_port) +while s2:size() ~= 2 do fiber.sleep(0.01) end +s1:size() +s2:size() + +s1.remove_member() +s1:remove_member(100) +s1:remove_member('1234') +s1:remove_member(uuid(2)) +s1:size() + +s1.add_member() +s1:add_member(100) +s1:add_member({uri = true}) +s1:add_member({uri = listen_uri}) +s1:add_member({uuid = uuid(2)}) +s1:add_member({uri = listen_uri, uuid = uuid(2)}) +s1:add_member({uri = listen_uri, uuid = uuid(2)}) +s1:size() + +s1:cfg({uuid = uuid(3)}) +-- Can't remove self. +s1:remove_member(uuid(3)) +-- Not existing. +s1:remove_member(uuid(4)) +-- Old self. +s1:remove_member(uuid(1)) + +s1:delete() +s2:delete() + +s1 = swim.new({uuid = uuid(1), uri = uri()}) +s2 = swim.new({uuid = uuid(2), uri = listen_uri}) +s1.probe_member() +s1:probe_member() +s1:probe_member(true) +-- Not existing URI is ok - nothing happens. +s1:probe_member('127.0.0.1:1') +fiber.yield() +s1:size() +s1:probe_member(listen_uri) +while s1:size() ~= 2 do fiber.sleep(0.01) end +s2:size() + +s1:delete() +s2:delete() + test_run:cmd("clear filter") -- 2.20.1 (Apple Git-117)