From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Ilya Kosarev Subject: [PATCH v2] iproto: report active connections number Date: Tue, 26 Feb 2019 01:36:07 +0300 Message-Id: <20190225223607.21729-1-i.kosarev@tarantool.org> To: tarantool-patches@freelists.org Cc: georgy@tarantool.org, vdavydov.dev@gmail.com, i.kosarev@corp.mail.ru, Ilya Kosarev List-ID: From: Ilya Kosarev Now there is new member in box.stat.net() called "CONNECTIONS" which is a number of active iproto connections. Closes #3905 --- https://github.com/tarantool/tarantool/tree/i.kosarev/gh-3905-report-connections-number https://github.com/tarantool/tarantool/issues/3905 Changes in v2: - CONNECTIONS counter doesn't count rps any more - Test became much more thorough src/box/iproto.cc | 17 +++++++++++++-- src/box/lua/stat.c | 44 +++++++++++++++++++++++++++++++++++++- test/box/stat_net.result | 43 +++++++++++++++++++++++++++++++++++++ test/box/stat_net.test.lua | 14 ++++++++++++ 4 files changed, 115 insertions(+), 3 deletions(-) diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 863eb4f06..386bab239 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -263,14 +263,20 @@ static struct cord net_cord; static struct slab_cache net_slabc; struct rmean *rmean_net; +struct rmean *rmean_connections; enum rmean_net_name { IPROTO_SENT, IPROTO_RECEIVED, IPROTO_LAST, }; +enum rmean_connection_name { + IPROTO_CONNECTIONS, + IPROTO_CONNECTIONS_LAST, +}; const char *rmean_net_strings[IPROTO_LAST] = { "SENT", "RECEIVED" }; +const char *rmean_connection_strings[IPROTO_CONNECTIONS_LAST] = { "CONNECTIONS" }; static void tx_process_destroy(struct cmsg *m); @@ -579,6 +585,8 @@ iproto_connection_close(struct iproto_connection *con) /* Make evio_has_fd() happy */ con->input.fd = con->output.fd = -1; close(fd); + /* Count statistics */ + rmean_collect(rmean_connections, IPROTO_CONNECTIONS, -1); /* * Discard unparsed data, to recycle the * connection in net_send_msg() as soon as all @@ -1858,6 +1866,8 @@ iproto_on_accept(struct evio_service * /* service */, int fd, struct iproto_connection *con = iproto_connection_new(fd); if (con == NULL) return -1; + /* Count statistics */ + rmean_collect(rmean_connections, IPROTO_CONNECTIONS, 1); /* * Ignore msg allocation failure - the queue size is * fixed so there is a limited number of msgs in @@ -1894,10 +1904,11 @@ net_cord_f(va_list /* ap */) iproto_on_accept, NULL); - /* Init statistics counter */ + /* Init statistics counters */ rmean_net = rmean_new(rmean_net_strings, IPROTO_LAST); + rmean_connections = rmean_new(rmean_connection_strings, IPROTO_CONNECTIONS_LAST); - if (rmean_net == NULL) { + if (rmean_net == NULL or rmean_connections == NULL) { tnt_raise(OutOfMemory, sizeof(struct rmean), "rmean", "struct rmean"); } @@ -1921,6 +1932,7 @@ net_cord_f(va_list /* ap */) evio_service_stop(&binary); rmean_delete(rmean_net); + rmean_delete(rmean_connections); return 0; } @@ -2125,6 +2137,7 @@ void iproto_reset_stat(void) { rmean_cleanup(rmean_net); + rmean_cleanup(rmean_connections); } void diff --git a/src/box/lua/stat.c b/src/box/lua/stat.c index 3fce81f61..f5b2ad7c1 100644 --- a/src/box/lua/stat.c +++ b/src/box/lua/stat.c @@ -50,6 +50,7 @@ extern struct rmean *rmean_box; extern struct rmean *rmean_error; /** network statistics (iproto & cbus) */ extern struct rmean *rmean_net; +extern struct rmean *rmean_connections; extern struct rmean *rmean_tx_wal_bus; static void @@ -79,6 +80,29 @@ set_stat_item(const char *name, int rps, int64_t total, void *cb_ctx) return 0; } +static void +fill_conn_item(struct lua_State *L, int64_t total) +{ + lua_pushstring(L, "total"); + lua_pushnumber(L, total); + lua_settable(L, -3); +} + +static int +set_conn_item(const char *name, int rps, int64_t total, void *cb_ctx) +{ + struct lua_State *L = (struct lua_State *) cb_ctx; + + lua_pushstring(L, name); + lua_newtable(L); + + fill_conn_item(L, total); + + lua_settable(L, -3); + + return rps - rps; +} + /** * A stat_foreach() callback used to handle access to e.g. * box.stats.DELETE. @@ -96,6 +120,19 @@ seek_stat_item(const char *name, int rps, int64_t total, void *cb_ctx) return 1; } +static int +seek_conn_item(const char *name, int rps, int64_t total, void *cb_ctx) +{ + struct lua_State *L = (struct lua_State *) cb_ctx; + if (strcmp(name, lua_tostring(L, -1)) != 0) + return rps - rps; + + lua_newtable(L); + fill_conn_item(L, total); + + return 1; +} + static int lbox_stat_index(struct lua_State *L) { @@ -140,7 +177,11 @@ static int lbox_stat_net_index(struct lua_State *L) { luaL_checkstring(L, -1); - return rmean_foreach(rmean_net, seek_stat_item, L); + if (rmean_foreach(rmean_net, seek_stat_item, L) == 1) + return 1; + if (rmean_foreach(rmean_connections, seek_conn_item, L) == 1) + return 1; + return 0; } static int @@ -148,6 +189,7 @@ lbox_stat_net_call(struct lua_State *L) { lua_newtable(L); rmean_foreach(rmean_net, set_stat_item, L); + rmean_foreach(rmean_connections, set_conn_item, L); return 1; } diff --git a/test/box/stat_net.result b/test/box/stat_net.result index b3e3db11f..dad932f8c 100644 --- a/test/box/stat_net.result +++ b/test/box/stat_net.result @@ -28,12 +28,24 @@ index = space:create_index('primary', { type = 'hash' }) remote = require 'net.box' --- ... +fiber = require 'fiber' +--- +... LISTEN = require('uri').parse(box.cfg.listen) --- ... cn = remote.connect(LISTEN.host, LISTEN.service) --- ... +cn1 = remote.connect(LISTEN.host, LISTEN.service) +--- +... +cn2 = remote.connect(LISTEN.host, LISTEN.service) +--- +... +cn3 = remote.connect(LISTEN.host, LISTEN.service) +--- +... cn.space.tweedledum:select() --small request --- - [] @@ -46,8 +58,35 @@ box.stat.net.RECEIVED.total > 0 --- - true ... +box.stat.net.CONNECTIONS.total == 4 +--- +- true +... -- box.stat.net.EVENTS.total > 0 -- box.stat.net.LOCKS.total > 0 +cn1:close() +--- +... +cn2:close() +--- +... +fiber.sleep(0.001) +--- +... +box.stat.net.CONNECTIONS.total == 2 +--- +- true +... +cn3:close() +--- +... +fiber.sleep(0.01) +--- +... +box.stat.net.CONNECTIONS.total == 1 +--- +- true +... -- reset box.stat.reset() --- @@ -60,6 +99,10 @@ box.stat.net.RECEIVED.total --- - 0 ... +box.stat.net.CONNECTIONS.total +--- +- 0 +... space:drop() -- tweedledum --- ... diff --git a/test/box/stat_net.test.lua b/test/box/stat_net.test.lua index 808bb71e7..9b379f6dd 100644 --- a/test/box/stat_net.test.lua +++ b/test/box/stat_net.test.lua @@ -10,21 +10,35 @@ space = box.schema.space.create('tweedledum') box.schema.user.grant('guest', 'read', 'space', 'tweedledum') index = space:create_index('primary', { type = 'hash' }) remote = require 'net.box' +fiber = require 'fiber' LISTEN = require('uri').parse(box.cfg.listen) cn = remote.connect(LISTEN.host, LISTEN.service) +cn1 = remote.connect(LISTEN.host, LISTEN.service) +cn2 = remote.connect(LISTEN.host, LISTEN.service) +cn3 = remote.connect(LISTEN.host, LISTEN.service) cn.space.tweedledum:select() --small request box.stat.net.SENT.total > 0 box.stat.net.RECEIVED.total > 0 +box.stat.net.CONNECTIONS.total == 4 -- box.stat.net.EVENTS.total > 0 -- box.stat.net.LOCKS.total > 0 +cn1:close() +cn2:close() +fiber.sleep(0.001) +box.stat.net.CONNECTIONS.total == 2 +cn3:close() +fiber.sleep(0.01) +box.stat.net.CONNECTIONS.total == 1 + -- reset box.stat.reset() box.stat.net.SENT.total box.stat.net.RECEIVED.total +box.stat.net.CONNECTIONS.total space:drop() -- tweedledum cn:close() -- 2.17.1