--- a/.hgtags Mon Dec 20 20:46:24 2021 +0000
+++ b/.hgtags Mon Dec 20 23:12:08 2021 +0100
@@ -78,3 +78,4 @@
774811e2c6abfc5a1b1dd60007cf564bb7c1f969 0.11.8
d0e9ffccdef934af554ea2d4a5beb9a52e9e951d 0.11.9
d117b92fd8e459170a98a8dece7f3930f4b6aed7 0.11.10
+76b4e3f12b53fedae96402d87fa9ee79e704ce5e 0.11.11
--- a/plugins/mod_pep.lua Mon Dec 20 20:46:24 2021 +0000
+++ b/plugins/mod_pep.lua Mon Dec 20 23:12:08 2021 +0100
@@ -6,9 +6,11 @@
local st = require "util.stanza";
local calculate_hash = require "util.caps".calculate_hash;
local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
+local cache = require "util.cache";
local set = require "util.set";
local new_id = require "util.id".medium;
local storagemanager = require "core.storagemanager";
+local usermanager = require "core.usermanager";
local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event";
@@ -18,14 +20,29 @@
local empty_set = set_new();
+-- username -> object passed to module:add_items()
+local pep_service_items = {};
+
+-- size of caches with full pubsub service objects
+local service_cache_size = module:get_option_number("pep_service_cache_size", 1000);
+
-- username -> util.pubsub service object
-local services = {};
+local services = cache.new(service_cache_size, function (username, _)
+ local item = pep_service_items[username];
+ pep_service_items[username] = nil;
+ if item then
+ module:remove_item("pep-service", item);
+ end
+end):table();
+
+-- size of caches with smaller objects
+local info_cache_size = module:get_option_number("pep_info_cache_size", 10000);
-- username -> recipient -> set of nodes
-local recipients = {};
+local recipients = cache.new(info_cache_size):table();
-- caps hash -> set of nodes
-local hash_map = {};
+local hash_map = cache.new(info_cache_size):table();
local host = module.host;
@@ -50,18 +67,12 @@
function module.save()
return {
- services = services;
recipients = recipients;
};
end
function module.restore(data)
- services = data.services;
recipients = data.recipients;
- for username, service in pairs(services) do
- local user_bare = jid_join(username, host);
- module:add_item("pep-service", { service = service, jid = user_bare });
- end
end
function is_item_stanza(item)
@@ -181,12 +192,26 @@
end
end
+local nobody_service = pubsub.new({
+ service = pubsub.new({
+ node_defaults = {
+ ["max_items"] = 1;
+ ["persist_items"] = false;
+ ["access_model"] = "presence";
+ ["send_last_published_item"] = "on_sub_and_presence";
+ };
+ });
+});
+
function get_pep_service(username)
local user_bare = jid_join(username, host);
local service = services[username];
if service then
return service;
end
+ if not usermanager.user_exists(username, host) then
+ return nobody_service;
+ end
module:log("debug", "Creating pubsub service for user %q", username);
service = pubsub.new({
pep_username = username;
@@ -226,7 +251,9 @@
check_node_config = check_node_config;
});
services[username] = service;
- module:add_item("pep-service", { service = service, jid = user_bare });
+ local item = { service = service, jid = user_bare }
+ pep_service_items[username] = item;
+ module:add_item("pep-service", item);
return service;
end
@@ -459,3 +486,18 @@
reply:tag("item", { jid = user_bare, node = node, name = node_obj.config.title }):up();
end
end);
+
+module:hook_global("user-deleted", function(event)
+ if event.host ~= host then return end
+ local username = event.username;
+ local service = services[username];
+ if not service then return end
+ for node in pairs(service.nodes) do service:delete(node, true); end
+
+ local item = pep_service_items[username];
+ pep_service_items[username] = nil;
+ if item then module:remove_item("pep-service", item); end
+
+ recipients[username] = nil;
+end);
+