Revert "perf: buffer mod_vnc_lastactivity DB writes and flush periodically"

back to original code for further analysis and improvement

This reverts commit 83e578cb94.

Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/5>
This commit is contained in:
2026-07-16 04:26:15 +00:00
committed by marge
parent 256b5fdeb1
commit 658008606a
+5 -60
View File
@@ -26,44 +26,6 @@ local activity_store = module:open_store("activity", "map");
local remote_activity_store = module:open_store("remote_activity", "map");
local remote_avatar_update_store = module:open_store("remote_avatar", "map");
-- The store :set() calls go through mod_storage_sql (LuaDBI), which is a
-- blocking C client -- every write blocks the event loop for a DB round-trip.
-- These hooks fire on the presence/auth hot path, so doing the write inline
-- stalls the whole server under presence storms. Instead we buffer the
-- last-value-wins writes in memory (the IQ handlers already read from the
-- in-memory map/caches) and flush them periodically from a timer.
local FLUSH_INTERVAL = module:get_option_number("vnc_lastactivity_flush_interval", 5);
-- Pending writes, coalesced by user/contact. Only the most recent value per
-- key is kept, matching the "last value wins" semantics of the stores.
local pending_activity = {}; -- [username] = stamp (store key "last")
local pending_remote_activity = {}; -- [contact_bare] = stamp (store key "last")
local pending_remote_avatar = {}; -- [contact_bare] = stamp (store key "avatar")
local function flush_pending_writes()
for username, value in pairs(pending_activity) do
local ok, err = activity_store:set(username, "last", value);
if not ok then
module:log("warn", "flush activity_store:set(%s) failed: %s", username, tostring(err));
end
end
for contact_bare, value in pairs(pending_remote_activity) do
local ok, err = remote_activity_store:set(contact_bare, "last", value);
if not ok then
module:log("warn", "flush remote_activity_store:set(%s) failed: %s", contact_bare, tostring(err));
end
end
for contact_bare, value in pairs(pending_remote_avatar) do
local ok, err = remote_avatar_update_store:set(contact_bare, "avatar", value);
if not ok then
module:log("warn", "flush remote_avatar_update_store:set(%s) failed: %s", contact_bare, tostring(err));
end
end
for k in pairs(pending_activity) do pending_activity[k] = nil; end
for k in pairs(pending_remote_activity) do pending_remote_activity[k] = nil; end
for k in pairs(pending_remote_avatar) do pending_remote_avatar[k] = nil; end
end
local function getTableLng(tbl)
local getN = 0
for n in pairs(tbl) do
@@ -145,8 +107,8 @@ local map = {};
module:hook("authentication-success", function(event)
local session = event.session;
if session.username then
pending_activity[session.username] = 0;
end
local pers = activity_store:set(session.username, "last", 0);
end
end, 10);
@@ -177,7 +139,7 @@ module:hook("presence/bare", function(event)
remote_act_sessions[contact_bare] = nil;
remote_act_cache[contact_bare] = t;
-- module:log("info", "remote_act_cache for %s is now %s", contact_bare, remote_act_cache[contact_bare]);
pending_remote_activity[contact_bare] = t;
remote_activity_store:set(contact_bare, "last", t);
end
end
else
@@ -199,7 +161,7 @@ module:hook("presence/bare", function(event)
if (x_photo_update) then
-- module:log("info", "avatarupdate - need to store %s update for %s", x_photo_update, contact_bare);
local t = os.time();
pending_remote_avatar[contact_bare] = t;
remote_avatar_update_store:set(contact_bare, "avatar", t);
end
end
@@ -226,7 +188,7 @@ module:hook("pre-presence/bare", function(event)
end
if lastsession then
-- module:log("info", "last session gone - storing to activity_store for %s => %s", event.origin.username, s);
pending_activity[event.origin.username] = s;
local pers = activity_store:set(event.origin.username, "last", s);
end
end
end, 10);
@@ -451,20 +413,3 @@ end
module.restore = function(data)
map = data.map or {};
end
-- Flush buffered writes on a fixed cadence instead of on every presence/auth
-- event. Returning FLUSH_INTERVAL reschedules the timer. The DB I/O still
-- blocks the event loop while it runs, but once per interval rather than per
-- stanza.
module:add_timer(FLUSH_INTERVAL, function ()
flush_pending_writes();
return FLUSH_INTERVAL;
end);
-- Best-effort final flush so buffered writes are not lost on stop/reload.
module:hook_global("server-stopping", function ()
flush_pending_writes();
end);
module:hook("host-deactivating", function ()
flush_pending_writes();
end);