# HG changeset patch # User tmolitor # Date 1611987575 -3600 # Node ID 0b9501f82e63c6fb4e14a1066e525c7a38efb2d7 # Parent e5493a10c4d1e3bc94318d35cf917eadac02caaa mod_smacks: allow O(1) processing of delayed ack events This adds a stanza field to the eent if the stanza which triggered this event is known exactly. diff -r e5493a10c4d1 -r 0b9501f82e63 mod_smacks/mod_smacks.lua --- a/mod_smacks/mod_smacks.lua Sat Jan 30 07:17:33 2021 +0100 +++ b/mod_smacks/mod_smacks.lua Sat Jan 30 07:19:35 2021 +0100 @@ -116,13 +116,13 @@ }; end -local function delayed_ack_function(session) +local function delayed_ack_function(session, stanza) -- fire event only if configured to do so and our session is not already hibernated or destroyed if delayed_ack_timeout > 0 and session.awaiting_ack and not session.hibernating and not session.destroyed then session.log("debug", "Firing event 'smacks-ack-delayed', queue = %d", session.outgoing_stanza_queue and #session.outgoing_stanza_queue or 0); - module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue}); + module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue, stanza = stanza}); end session.delayed_ack_timer = nil; end @@ -158,7 +158,7 @@ end end); -local function request_ack_if_needed(session, force, reason) +local function request_ack_if_needed(session, force, reason, stanza) local queue = session.outgoing_stanza_queue; local expected_h = session.last_acknowledged_stanza + #queue; -- session.log("debug", "*** SMACKS(1) ***: awaiting_ack=%s, hibernating=%s", tostring(session.awaiting_ack), tostring(session.hibernating)); @@ -182,7 +182,7 @@ session.log("debug", "Sending (inside timer, after send) from %s - #queue=%d", reason, #queue); if not session.delayed_ack_timer then session.delayed_ack_timer = stoppable_timer(delayed_ack_timeout, function() - delayed_ack_function(session); + delayed_ack_function(session, nil); -- we don't know if this is the only new stanza in the queue end); end end @@ -196,7 +196,7 @@ -- would not trigger this event (again). if #queue > max_unacked_stanzas and session.awaiting_ack and session.delayed_ack_timer == nil then session.log("debug", "Calling delayed_ack_function directly (still waiting for ack)"); - delayed_ack_function(session); + delayed_ack_function(session, stanza); -- this is the only new stanza in the queue --> provide it to other modules end end @@ -228,7 +228,7 @@ module:fire_event("smacks-hibernation-stanza-queued", {origin = session, queue = queue, stanza = cached_stanza}); return nil; end - request_ack_if_needed(session, false, "outgoing_stanza_filter"); + request_ack_if_needed(session, false, "outgoing_stanza_filter", stanza); end return stanza; end @@ -348,7 +348,7 @@ -- piggyback our own ack request if needed (see request_ack_if_needed() for explanation of last_requested_h) local expected_h = origin.last_acknowledged_stanza + #origin.outgoing_stanza_queue; if #origin.outgoing_stanza_queue > 0 and expected_h ~= origin.last_requested_h then - request_ack_if_needed(origin, true, "piggybacked by handle_r"); + request_ack_if_needed(origin, true, "piggybacked by handle_r", nil); end return true; end @@ -390,7 +390,7 @@ origin.log("debug", "#queue = %d", #queue); origin.last_acknowledged_stanza = origin.last_acknowledged_stanza + handled_stanza_count; - request_ack_if_needed(origin, false, "handle_a") + request_ack_if_needed(origin, false, "handle_a", nil) return true; end module:hook_stanza(xmlns_sm2, "a", handle_a); @@ -623,7 +623,7 @@ return false; end module:fire_event("smacks-hibernation-end", {origin = session, resumed = original_session, queue = queue}); - request_ack_if_needed(original_session, true, "handle_resume"); + request_ack_if_needed(original_session, true, "handle_resume", nil); else module:log("warn", "Client %s@%s[%s] tried to resume stream for %s@%s[%s]", session.username or "?", session.host or "?", session.type, @@ -654,7 +654,7 @@ session.awaiting_ack = true; if not session.delayed_ack_timer then session.delayed_ack_timer = stoppable_timer(delayed_ack_timeout, function() - delayed_ack_function(session); + delayed_ack_function(session, nil); end); end return true;