# HG changeset patch # User tmolitor # Date 1503013756 -7200 # Node ID b62cec32680e0888a5db400fe07ee2d27f4455df # Parent f70c02c14161db0937aefd9f6840e39bc90bf3cc 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 diff -r f70c02c14161 -r b62cec32680e mod_csi_battery_saver/README.markdown --- 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 diff -r f70c02c14161 -r b62cec32680e mod_csi_battery_saver/mod_csi_battery_saver.lua --- 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