changeset 4413:0b9501f82e63

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.
author tmolitor <thilo@eightysoft.de>
date Sat, 30 Jan 2021 07:19:35 +0100
parents e5493a10c4d1
children dbfa830e4504
files mod_smacks/mod_smacks.lua
diffstat 1 files changed, 10 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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 <r> (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;