feat: Several module optimizations to avoid constant parsing of jids. (#12594)
* feat: Several module optimizations to avoid constant parsing of jids. Caches the parsed values in a rotating table with limited size. Skips constant creating of a stanza with never changing values - create it once and then just clone it. * squash: Fixes extract_subdomain multiple values. * squash: Fix table values when there is a nil element. * squash: Fix skipping the roomless IQs. * squash: Fix comments.
This commit is contained in:
parent
76471a0ea9
commit
744960bb1a
|
@ -22,21 +22,30 @@ if release_number_config then
|
|||
module:add_identity("server", "release", release_number_config);
|
||||
end
|
||||
|
||||
-- we cache the query as server identities will not change dynamically, amd use its clone every time
|
||||
local query_cache;
|
||||
|
||||
-- this is after xmpp-bind, the moment a client has resource and can be contacted
|
||||
module:hook("resource-bind", function (event)
|
||||
local session = event.session;
|
||||
|
||||
-- disco info data / all identity and features
|
||||
local query = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info" });
|
||||
local done = {};
|
||||
for _,identity in ipairs(module:get_host_items("identity")) do
|
||||
local identity_s = identity.category.."\0"..identity.type;
|
||||
if not done[identity_s] then
|
||||
query:tag("identity", identity):up();
|
||||
done[identity_s] = true;
|
||||
if query_cache == nil then
|
||||
-- disco info data / all identity and features
|
||||
local query = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info" });
|
||||
local done = {};
|
||||
for _,identity in ipairs(module:get_host_items("identity")) do
|
||||
local identity_s = identity.category.."\0"..identity.type;
|
||||
if not done[identity_s] then
|
||||
query:tag("identity", identity):up();
|
||||
done[identity_s] = true;
|
||||
end
|
||||
end
|
||||
|
||||
query_cache = query;
|
||||
end
|
||||
|
||||
local query = st.clone(query_cache);
|
||||
|
||||
-- check whether room has lobby enabled and display name is required for those trying to join
|
||||
local lobby_muc_component_config = module:get_option_string('lobby_muc');
|
||||
module:context(lobby_muc_component_config):fire_event('host-disco-info-node',
|
||||
|
|
|
@ -273,9 +273,7 @@ end
|
|||
-- and was not successful
|
||||
function Util:verify_room(session, room_address)
|
||||
if self.allowEmptyToken and session.auth_token == nil then
|
||||
module:log(
|
||||
"debug",
|
||||
"Skipped room token verification - empty tokens are allowed");
|
||||
--module:log("debug", "Skipped room token verification - empty tokens are allowed");
|
||||
return true;
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
local jid = require "util.jid";
|
||||
local timer = require "util.timer";
|
||||
local http = require "net.http";
|
||||
local cache = require "util.cache";
|
||||
|
||||
local http_timeout = 30;
|
||||
local have_async, async = pcall(require, "util.async");
|
||||
|
@ -25,18 +26,24 @@ local target_subdomain_pattern = "^"..escaped_muc_domain_prefix..".([^%.]+)%."..
|
|||
-- table to store all incoming iqs without roomname in it, like discoinfo to the muc component
|
||||
local roomless_iqs = {};
|
||||
|
||||
local split_subdomain_cache = cache.new(1000);
|
||||
local extract_subdomain_cache = cache.new(1000);
|
||||
local internal_room_jid_cache = cache.new(1000);
|
||||
|
||||
-- Utility function to split room JID to include room name and subdomain
|
||||
-- (e.g. from room1@conference.foo.example.com/res returns (room1, example.com, res, foo))
|
||||
local function room_jid_split_subdomain(room_jid)
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
|
||||
-- optimization, skip matching if there is no subdomain or it is not the muc component address at all
|
||||
if host == muc_domain or not starts_with(host, muc_domain_prefix) then
|
||||
return node, host, resource;
|
||||
local ret = split_subdomain_cache:get(room_jid);
|
||||
if ret then
|
||||
return ret.node, ret.host, ret.resource, ret.subdomain;
|
||||
end
|
||||
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
|
||||
local target_subdomain = host and host:match(target_subdomain_pattern);
|
||||
return node, host, resource, target_subdomain
|
||||
local cache_value = {node=node, host=host, resource=resource, subdomain=target_subdomain};
|
||||
split_subdomain_cache:set(room_jid, cache_value);
|
||||
return node, host, resource, target_subdomain;
|
||||
end
|
||||
|
||||
--- Utility function to check and convert a room JID from
|
||||
|
@ -69,27 +76,36 @@ end
|
|||
|
||||
-- Utility function to check and convert a room JID from real [foo]room1@muc.example.com to virtual room1@muc.foo.example.com
|
||||
local function internal_room_jid_match_rewrite(room_jid, stanza)
|
||||
-- first check for roomless_iqs
|
||||
if (stanza and stanza.attr and stanza.attr.id and roomless_iqs[stanza.attr.id]) then
|
||||
local result = roomless_iqs[stanza.attr.id];
|
||||
roomless_iqs[stanza.attr.id] = nil;
|
||||
return result;
|
||||
end
|
||||
|
||||
local ret = internal_room_jid_cache:get(room_jid);
|
||||
if ret then
|
||||
return ret;
|
||||
end
|
||||
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
if host ~= muc_domain or not node then
|
||||
-- module:log("debug", "No need to rewrite %s (not from the MUC host)", room_jid);
|
||||
|
||||
if (stanza and stanza.attr and stanza.attr.id and roomless_iqs[stanza.attr.id]) then
|
||||
local result = roomless_iqs[stanza.attr.id];
|
||||
roomless_iqs[stanza.attr.id] = nil;
|
||||
return result;
|
||||
end
|
||||
|
||||
internal_room_jid_cache:set(room_jid, room_jid);
|
||||
return room_jid;
|
||||
end
|
||||
|
||||
local target_subdomain, target_node = extract_subdomain(node);
|
||||
if not (target_node and target_subdomain) then
|
||||
-- module:log("debug", "Not rewriting... unexpected node format: %s", node);
|
||||
internal_room_jid_cache:set(room_jid, room_jid);
|
||||
return room_jid;
|
||||
end
|
||||
|
||||
-- Ok, rewrite room_jid address to pretty format
|
||||
return jid.join(target_node, muc_domain_prefix..".".. target_subdomain.."."..muc_domain_base, resource);
|
||||
ret = jid.join(target_node, muc_domain_prefix..".".. target_subdomain.."."..muc_domain_base, resource);
|
||||
internal_room_jid_cache:set(room_jid, ret);
|
||||
return ret;
|
||||
end
|
||||
|
||||
--- Finds and returns room by its jid
|
||||
|
@ -242,12 +258,15 @@ end
|
|||
--- Extracts the subdomain and room name from internal jid node [foo]room1
|
||||
-- @return subdomain(optional, if extracted or nil), the room name
|
||||
function extract_subdomain(room_node)
|
||||
-- optimization, skip matching if there is no subdomain, no [subdomain] part in the beginning of the node
|
||||
if not starts_with(room_node, '[') then
|
||||
return nil,room_node;
|
||||
local ret = extract_subdomain_cache:get(room_node);
|
||||
if ret then
|
||||
return ret.subdomain, ret.room;
|
||||
end
|
||||
|
||||
return room_node:match("^%[([^%]]+)%](.+)$");
|
||||
local subdomain, room_name = room_node:match("^%[([^%]]+)%](.+)$");
|
||||
local cache_value = {subdomain=subdomain, room=room_name};
|
||||
extract_subdomain_cache:set(room_node, cache_value);
|
||||
return subdomain, room_name;
|
||||
end
|
||||
|
||||
function starts_with(str, start)
|
||||
|
@ -260,11 +279,7 @@ end
|
|||
|
||||
-- healthcheck rooms in jicofo starts with a string '__jicofo-health-check'
|
||||
function is_healthcheck_room(room_jid)
|
||||
if starts_with(room_jid, "__jicofo-health-check") then
|
||||
return true;
|
||||
end
|
||||
|
||||
return false;
|
||||
return starts_with(room_jid, "__jicofo-health-check");
|
||||
end
|
||||
|
||||
--- Utility function to make an http get request and
|
||||
|
|
Loading…
Reference in New Issue