changeset 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
parents 3b2c94ea0c2e
children 2e641ab995b3
files mod_smacks/README.markdown mod_smacks/mod_smacks.lua
diffstat 2 files changed, 37 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mod_smacks/README.markdown	Tue Nov 22 21:15:01 2016 +0100
+++ b/mod_smacks/README.markdown	Thu Nov 24 00:47:32 2016 +0100
@@ -31,6 +31,14 @@
 offline as normal, and any stanzas in the queue are returned to the
 sender as a "recipient-unavailable" error.
 
+If you don't want this behaviour on timeout you can use [mod_smacks_offline]
+or [mod_smacks_noerror] to customize the behaviour further.
+
+This module also provides some events used by [mod_cloud_notify].
+These events are: "smacks-ack-delayed", "smacks-hibernation-start" and
+"smacks-hibernation-end". See [mod_cloud_notify] for details on how this
+events are used there.
+
 Configuration
 =============
 
@@ -39,11 +47,13 @@
   `smacks_hibernation_time`      300 (5 minutes)   The number of seconds a disconnected session should stay alive for (to allow reconnect)
   `smacks_enabled_s2s`           false             Enable Stream Management on server connections? *Experimental*
   `smacks_max_unacked_stanzas`   0                 How many stanzas to send before requesting acknowledgement
+  `smacks_max_ack_delay`         60 (1 minute)     The number of seconds an ack must be unanswered to trigger an "smacks-ack-delayed" event
 
 Compatibility
 =============
 
   ----- -----------------------------------
+  0.10  Works
   0.9   Works
   0.8   Works, use version [7693724881b3]
   ----- -----------------------------------
@@ -61,3 +71,6 @@
 -   Yaxim
 
 [7693724881b3]: //hg.prosody.im/prosody-modules/raw-file/7693724881b3/mod_smacks/mod_smacks.lua
+[mod_smacks_offline]: //modules.prosody.im/mod_smacks_offline
+[mod_smacks_noerror]: //modules.prosody.im/mod_smacks_noerror
+[mod_cloud_notify]: //modules.prosody.im/mod_cloud_notify
--- 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