comparison mod_csi_battery_saver/mod_csi_battery_saver.lua @ 2741:69248dcd7cff

mod_csi_battery_saver: Fix interaction with smacks hibernation This should fix a bug that caused the module to be deactivated on smacks resume. Also update the readme accordingly,
author tmolitor <thilo@eightysoft.de>
date Thu, 17 Aug 2017 21:21:23 +0200
parents f43c77c69a8a
children 2e30bb3a10d5
comparison
equal deleted inserted replaced
2737:f43c77c69a8a 2741:69248dcd7cff
7 local s_match = string.match; 7 local s_match = string.match;
8 local s_sub = string.sub; 8 local s_sub = string.sub;
9 local jid = require "util.jid"; 9 local jid = require "util.jid";
10 local new_queue = require "util.queue".new; 10 local new_queue = require "util.queue".new;
11 local datetime = require "util.datetime"; 11 local datetime = require "util.datetime";
12 local clone = require "util.stanza".clone; 12 local st = require "util.stanza";
13 13
14 local xmlns_delay = "urn:xmpp:delay"; 14 local xmlns_delay = "urn:xmpp:delay";
15 15
16 -- a log id for this module instance 16 -- a log id for this module instance
17 local id = s_sub(require "util.hashes".sha256(datetime.datetime(), true), 1, 4); 17 local id = s_sub(require "util.hashes".sha256(datetime.datetime(), true), 1, 4);
55 flush = true; 55 flush = true;
56 return q:flush(); 56 return q:flush();
57 end 57 end
58 local push = q.push; 58 local push = q.push;
59 function q:push(item) 59 function q:push(item)
60 local ok = push(self, clone(item)); 60 local ok = push(self, item);
61 if not ok then 61 if not ok then
62 q:flush(); 62 q:flush();
63 output(item, self); 63 output(item, self);
64 elseif flush then 64 elseif flush then
65 return q:flush(); 65 return q:flush();
93 return stanza; 93 return stanza;
94 end 94 end
95 95
96 local function is_important(stanza, session) 96 local function is_important(stanza, session)
97 local st_name = stanza and stanza.name or nil; 97 local st_name = stanza and stanza.name or nil;
98 if not st_name then return false; end 98 if not st_name then return true; end -- nonzas are always important
99 if st_name == "presence" then 99 if st_name == "presence" then
100 -- TODO check for MUC status codes? 100 -- TODO check for MUC status codes?
101 return false; 101 return false;
102 elseif st_name == "message" then 102 elseif st_name == "message" then
103 -- unpack carbon copies 103 -- unpack carbon copies
146 end 146 end
147 147
148 module:hook("csi-client-inactive", function (event) 148 module:hook("csi-client-inactive", function (event)
149 local session = event.origin; 149 local session = event.origin;
150 if session.pump then 150 if session.pump then
151 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive, buffering unimportant stanzas", id);
151 session.pump:pause(); 152 session.pump:pause();
152 else 153 else
153 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive the first time, initializing module for this session", id); 154 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive the first time, initializing module for this session", id);
154 local pump = new_pump(session.send, 100); 155 local pump = new_pump(session.send, 100);
155 pump:pause(); 156 pump:pause();
156 session.pump = pump; 157 session.pump = pump;
157 session._pump_orig_send = session.send; 158 session._pump_orig_send = session.send;
158 function session.send(stanza) 159 function session.send(stanza)
159 session.log("debug", "mod_csi_battery_saver(%s): Got stanza: <%s>", id, tostring(stanza.name)); 160 session.log("debug", "mod_csi_battery_saver(%s): Got stanza: <%s>", id, tostring(stanza.name or stanza));
160 local important = is_important(stanza, session); 161 local important = is_important(stanza, session);
161 -- add delay stamp to unimportant (buffered) stanzas that can/need be stamped 162 -- add delay stamp to unimportant (buffered) stanzas that can/need be stamped
162 if not important and is_stamp_needed(stanza, session) then stanza = add_stamp(stanza, session); end 163 if not important and is_stamp_needed(stanza, session) then stanza = add_stamp(stanza, session); end
163 pump:push(stanza); 164 pump:push(stanza);
164 if important then 165 if important then
165 session.log("debug", "mod_csi_battery_saver(%s): Encountered important stanza, flushing buffer: <%s>", id, tostring(stanza.name)); 166 session.log("debug", "mod_csi_battery_saver(%s): Encountered important stanza, flushing buffer: <%s>", id, tostring(stanza.name or stanza));
166 pump:flush(); 167 pump:flush();
167 end 168 end
168 return true; 169 return true;
169 end 170 end
170 end 171 end
171 session.log("debug", "mod_csi_battery_saver(%s): Client is inactive, buffering unimportant stanzas", id);
172 end); 172 end);
173 173
174 module:hook("csi-client-active", function (event) 174 module:hook("csi-client-active", function (event)
175 local session = event.origin; 175 local session = event.origin;
176 if session.pump then 176 if session.pump then
177 session.log("debug", "mod_csi_battery_saver(%s): Client is active, resuming direct delivery", id); 177 session.log("debug", "mod_csi_battery_saver(%s): Client is active, resuming direct delivery", id);
178 session.pump:resume(); 178 session.pump:resume();
179 end 179 end
180 end); 180 end);
181 181
182 -- clean up this session
183 local function remove_pump(session)
184 if session.pump then
185 session.log("debug", "mod_csi_battery_saver(%s): Flushing buffer and restoring to original session.send()", id);
186 session.pump:flush();
187 session.send = session._pump_orig_send;
188 session.pump = nil;
189 session._pump_orig_send = nil;
190 end
191 end
192
193 -- clean up this session on hibernation start
194 module:hook("smacks-hibernation-start", function (event)
195 remove_pump(event.origin);
196 end);
197
182 function module.unload() 198 function module.unload()
183 module:log("info", "%s: Unloading module, flushing all buffers", id); 199 module:log("info", "%s: Unloading module, flushing all buffers", id);
184 local host_sessions = prosody.hosts[module.host].sessions; 200 local host_sessions = prosody.hosts[module.host].sessions;
185 for _, user in pairs(host_sessions) do 201 for _, user in pairs(host_sessions) do
186 for _, session in pairs(user.sessions) do 202 for _, session in pairs(user.sessions) do
187 if session.pump then 203 remove_pump(session);
188 session.pump:flush();
189 session.send = session._pump_orig_send;
190 session.pump = nil;
191 session._pump_orig_send = nil;
192 end
193 end 204 end
194 end 205 end
195 end 206 end
196 207
197 module:log("info", "%s: Successfully loaded module", id); 208 module:log("info", "%s: Successfully loaded module", id);