Changeset

2745:b62cec32680e

mod_csi_battery_saver: Fix bug when smacks is resumed before hibernating This needs a mod_smacks version at least as new as of commit f70c02c14161 otherwise message reordering could happen
author tmolitor <thilo@eightysoft.de>
date Fri, 18 Aug 2017 01:49:16 +0200
parents 2744:f70c02c14161
children 2746:d3a2f4bdaf09
files mod_csi_battery_saver/README.markdown mod_csi_battery_saver/mod_csi_battery_saver.lua
diffstat 2 files changed, 34 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/mod_csi_battery_saver/README.markdown	Fri Aug 18 00:56:38 2017 +0200
+++ b/mod_csi_battery_saver/README.markdown	Fri Aug 18 01:49:16 2017 +0200
@@ -8,6 +8,9 @@
 properly handled carbon copies, support for handling encrypted messages and
 correctly handled smacks events.
 
+If smacks is used on the same server this needs at least version [f70c02c14161]
+of the smacks module! There could be message reordering on resume otherwise.
+
 Stanzas are queued in a buffer until either an "important" stanza is
 encountered or the buffer becomes full. Then all queued stanzas are sent
 at the same time. This way, nothing is lost or reordered while still
@@ -26,3 +29,5 @@
 [mod_filter_chatstates] or [mod_csi_pump] is *not* supported.
 
 The internal stanza buffer of this module is hardcoded to 100 stanzas.
+
+[f70c02c14161]: //hg.prosody.im/prosody-modules/raw-file/f70c02c14161/mod_smacks/mod_smacks.lua
\ No newline at end of file
--- a/mod_csi_battery_saver/mod_csi_battery_saver.lua	Fri Aug 18 00:56:38 2017 +0200
+++ b/mod_csi_battery_saver/mod_csi_battery_saver.lua	Fri Aug 18 01:49:16 2017 +0200
@@ -66,10 +66,11 @@
 		end
 		return true;
 	end
-	function q:flush()
+	function q:flush(alternative_output)
+		local out = alternative_output or output;
 		local item = self:pop();
 		while item do
-			output(item, self);
+			out(item, self);
 			item = self:pop();
 		end
 		return true;
@@ -148,7 +149,7 @@
 module:hook("csi-client-inactive", function (event)
 	local session = event.origin;
 	if session.pump then
-		session.log("debug", "mod_csi_battery_saver(%s): Client is inactive, buffering unimportant stanzas", id);
+		session.log("debug", "mod_csi_battery_saver(%s): Client is inactive, buffering unimportant outgoing stanzas", id);
 		session.pump:pause();
 	else
 		session.log("debug", "mod_csi_battery_saver(%s): Client is inactive the first time, initializing module for this session", id);
@@ -157,7 +158,7 @@
 		session.pump = pump;
 		session._pump_orig_send = session.send;
 		function session.send(stanza)
-			session.log("debug", "mod_csi_battery_saver(%s): Got stanza: <%s>", id, tostring(stanza.name or stanza));
+			session.log("debug", "mod_csi_battery_saver(%s): Got outgoing stanza: <%s>", id, tostring(stanza.name or stanza));
 			local important = is_important(stanza, session);
 			-- clone stanzas before adding delay stamp and putting them into the queue
 			if st.is_stanza(stanza) then stanza = st.clone(stanza); end
@@ -182,20 +183,30 @@
 	end
 end);
 
--- clean up this session
-local function remove_pump(session)
+-- clean up this session on hibernation start
+module:hook("smacks-hibernation-start", function (event)
+	local session = event.origin;
 	if session.pump then
-		session.log("debug", "mod_csi_battery_saver(%s): Flushing buffer and restoring to original session.send()", id);
+		session.log("debug", "mod_csi_battery_saver(%s): Hibernation started, flushing buffer and afterwards disabling for this session", id);
 		session.pump:flush();
 		session.send = session._pump_orig_send;
 		session.pump = nil;
 		session._pump_orig_send = nil;
 	end
-end
+end);
 
--- clean up this session on hibernation start
-module:hook("smacks-hibernation-start", function (event)
-	remove_pump(event.origin);
+-- clean up this session on hibernation end as well
+-- but don't change resumed.send(), it is already overwritten with session.send() by the smacks module
+module:hook("smacks-hibernation-end", function (event)
+	local session = event.resumed;
+	if session.pump then
+		session.log("debug", "mod_csi_battery_saver(%s): Hibernation ended without being started, flushing buffer and afterwards disabling for this session", id);
+		session.pump:flush(session.send);		-- use the fresh session.send() introduced by the smacks resume
+		-- don't reset session.send() because this is not the send previously overwritten by this module, but a fresh one
+		-- session.send = session._pump_orig_send;
+		session.pump = nil;
+		session._pump_orig_send = nil;
+	end
 end);
 
 function module.unload()
@@ -203,7 +214,13 @@
 	local host_sessions = prosody.hosts[module.host].sessions;
 	for _, user in pairs(host_sessions) do
 		for _, session in pairs(user.sessions) do
-			remove_pump(session);
+			if session.pump then
+				session.log("debug", "mod_csi_battery_saver(%s): Flushing buffer and restoring to original session.send()", id);
+				session.pump:flush();
+				session.send = session._pump_orig_send;
+				session.pump = nil;
+				session._pump_orig_send = nil;
+			end
 		end
 	end
 end