comparison mod_csi_battery_saver/mod_csi_battery_saver.lua @ 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 2e30bb3a10d5
children d3a2f4bdaf09
comparison
equal deleted inserted replaced
2744:f70c02c14161 2745:b62cec32680e
64 elseif flush then 64 elseif flush then
65 return q:flush(); 65 return q:flush();
66 end 66 end
67 return true; 67 return true;
68 end 68 end
69 function q:flush() 69 function q:flush(alternative_output)
70 local out = alternative_output or output;
70 local item = self:pop(); 71 local item = self:pop();
71 while item do 72 while item do
72 output(item, self); 73 out(item, self);
73 item = self:pop(); 74 item = self:pop();
74 end 75 end
75 return true; 76 return true;
76 end 77 end
77 return q; 78 return q;
146 end 147 end
147 148
148 module:hook("csi-client-inactive", function (event) 149 module:hook("csi-client-inactive", function (event)
149 local session = event.origin; 150 local session = event.origin;
150 if session.pump then 151 if session.pump then
151 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive, buffering unimportant stanzas", id); 152 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive, buffering unimportant outgoing stanzas", id);
152 session.pump:pause(); 153 session.pump:pause();
153 else 154 else
154 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive the first time, initializing module for this session", id); 155 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive the first time, initializing module for this session", id);
155 local pump = new_pump(session.send, 100); 156 local pump = new_pump(session.send, 100);
156 pump:pause(); 157 pump:pause();
157 session.pump = pump; 158 session.pump = pump;
158 session._pump_orig_send = session.send; 159 session._pump_orig_send = session.send;
159 function session.send(stanza) 160 function session.send(stanza)
160 session.log("debug", "mod_csi_battery_saver(%s): Got stanza: <%s>", id, tostring(stanza.name or stanza)); 161 session.log("debug", "mod_csi_battery_saver(%s): Got outgoing stanza: <%s>", id, tostring(stanza.name or stanza));
161 local important = is_important(stanza, session); 162 local important = is_important(stanza, session);
162 -- clone stanzas before adding delay stamp and putting them into the queue 163 -- clone stanzas before adding delay stamp and putting them into the queue
163 if st.is_stanza(stanza) then stanza = st.clone(stanza); end 164 if st.is_stanza(stanza) then stanza = st.clone(stanza); end
164 -- add delay stamp to unimportant (buffered) stanzas that can/need be stamped 165 -- add delay stamp to unimportant (buffered) stanzas that can/need be stamped
165 if not important and is_stamp_needed(stanza, session) then stanza = add_stamp(stanza, session); end 166 if not important and is_stamp_needed(stanza, session) then stanza = add_stamp(stanza, session); end
180 session.log("debug", "mod_csi_battery_saver(%s): Client is active, resuming direct delivery", id); 181 session.log("debug", "mod_csi_battery_saver(%s): Client is active, resuming direct delivery", id);
181 session.pump:resume(); 182 session.pump:resume();
182 end 183 end
183 end); 184 end);
184 185
185 -- clean up this session 186 -- clean up this session on hibernation start
186 local function remove_pump(session) 187 module:hook("smacks-hibernation-start", function (event)
187 if session.pump then 188 local session = event.origin;
188 session.log("debug", "mod_csi_battery_saver(%s): Flushing buffer and restoring to original session.send()", id); 189 if session.pump then
190 session.log("debug", "mod_csi_battery_saver(%s): Hibernation started, flushing buffer and afterwards disabling for this session", id);
189 session.pump:flush(); 191 session.pump:flush();
190 session.send = session._pump_orig_send; 192 session.send = session._pump_orig_send;
191 session.pump = nil; 193 session.pump = nil;
192 session._pump_orig_send = nil; 194 session._pump_orig_send = nil;
193 end 195 end
194 end 196 end);
195 197
196 -- clean up this session on hibernation start 198 -- clean up this session on hibernation end as well
197 module:hook("smacks-hibernation-start", function (event) 199 -- but don't change resumed.send(), it is already overwritten with session.send() by the smacks module
198 remove_pump(event.origin); 200 module:hook("smacks-hibernation-end", function (event)
201 local session = event.resumed;
202 if session.pump then
203 session.log("debug", "mod_csi_battery_saver(%s): Hibernation ended without being started, flushing buffer and afterwards disabling for this session", id);
204 session.pump:flush(session.send); -- use the fresh session.send() introduced by the smacks resume
205 -- don't reset session.send() because this is not the send previously overwritten by this module, but a fresh one
206 -- session.send = session._pump_orig_send;
207 session.pump = nil;
208 session._pump_orig_send = nil;
209 end
199 end); 210 end);
200 211
201 function module.unload() 212 function module.unload()
202 module:log("info", "%s: Unloading module, flushing all buffers", id); 213 module:log("info", "%s: Unloading module, flushing all buffers", id);
203 local host_sessions = prosody.hosts[module.host].sessions; 214 local host_sessions = prosody.hosts[module.host].sessions;
204 for _, user in pairs(host_sessions) do 215 for _, user in pairs(host_sessions) do
205 for _, session in pairs(user.sessions) do 216 for _, session in pairs(user.sessions) do
206 remove_pump(session); 217 if session.pump then
218 session.log("debug", "mod_csi_battery_saver(%s): Flushing buffer and restoring to original session.send()", id);
219 session.pump:flush();
220 session.send = session._pump_orig_send;
221 session.pump = nil;
222 session._pump_orig_send = nil;
223 end
207 end 224 end
208 end 225 end
209 end 226 end
210 227
211 module:log("info", "%s: Successfully loaded module", id); 228 module:log("info", "%s: Successfully loaded module", id);