Diff

mod_smacks/mod_smacks.lua @ 2394:4c27ebcf4cbd

mod_smacks: added new event "smacks-ack-delayed" used by mod_cloud_notify and extended the readme file accordingly (also mention mod_smacks_offline and mod_smacks_noerror in readme file)
author tmolitor <thilo@eightysoft.de>
date Thu, 24 Nov 2016 00:47:32 +0100
parent 2251:48c3d64a3fc1
child 2417:5e7badecf7fe
line wrap: on
line diff
--- a/mod_smacks/mod_smacks.lua	Tue Nov 22 21:15:01 2016 +0100
+++ b/mod_smacks/mod_smacks.lua	Thu Nov 24 00:47:32 2016 +0100
@@ -5,6 +5,7 @@
 -- Copyright (C) 2012-2015 Kim Alvefur
 -- Copyright (C) 2012 Thijs Alkemade
 -- Copyright (C) 2014 Florian Zeitz
+-- Copyright (C) 2016 Thilo Molitor
 --
 -- This project is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
@@ -33,12 +34,21 @@
 local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", false);
 local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false);
 local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0);
+local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 60);
 local core_process_stanza = prosody.core_process_stanza;
 local sessionmanager = require"core.sessionmanager";
 
 local c2s_sessions = module:shared("/*/c2s/sessions");
 local session_registry = {};
 
+local function delayed_ack_function(session)
+	-- fire event only when configured to do so
+	if delayed_ack_timeout > 0 and session.awaiting_ack and not session.outgoing_stanza_queue == nil then
+		session.log("debug", "Firing event 'smacks-ack-delayed', queue = %d", #session.outgoing_stanza_queue);
+		module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue});
+	end
+end
+
 local function can_do_smacks(session, advertise_only)
 	if session.smacks then return false, "unexpected-request", "Stream management is already enabled"; end
 
@@ -92,9 +102,13 @@
 			session.awaiting_ack = false;
 			session.awaiting_ack_timer = module:add_timer(1e-06, function ()
 				if not session.awaiting_ack then
-					session.log("debug", "Sending <r> (after send)");
+					session.log("debug", "Sending <r> (before send)");
 					(session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks }))
+					session.log("debug", "Sending <r> (after send)");
 					session.awaiting_ack = true;
+					session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function()
+						delayed_ack_function(session);
+					end);
 				end
 			end);
 		end
@@ -220,6 +234,9 @@
 	if origin.awaiting_ack_timer then
 		origin.awaiting_ack_timer:stop();
 	end
+	if origin.delayed_ack_timer then
+		origin.delayed_ack_timer:stop();
+	end
 	-- Remove handled stanzas from outgoing_stanza_queue
 	--log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or "");
 	local h = tonumber(stanza.attr.h);
@@ -405,12 +422,18 @@
 			if session.awaiting_ack_timer then
 				session.awaiting_ack_timer:stop();
 			end
+			if session.delayed_ack_timer then
+				session.delayed_ack_timer:stop();
+			end
 			return false; -- Kick the session
 		end
 		session.log("debug", "Sending <r> (read timeout)");
 		session.awaiting_ack = false;
 		(session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks }));
 		session.awaiting_ack = true;
+		session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function()
+			delayed_ack_function(session);
+		end);
 		return true;
 	end
 end