comparison mod_smacks/mod_smacks.lua @ 2494:d300ae5dba87

mod_smacks: Fix some bugs with smacks-ack-delayed event triggering. The old code had several flaws which are addressed here. First of all this fixes the if statement guarding the event generation There where some timing glitches addressed by this commit as well.
author tmolitor <thilo@eightysoft.de>
date Sun, 12 Feb 2017 21:23:22 +0100
parents 5fbca7de2088
children ffb6646b4253
comparison
equal deleted inserted replaced
2491:5fbca7de2088 2494:d300ae5dba87
41 local c2s_sessions = module:shared("/*/c2s/sessions"); 41 local c2s_sessions = module:shared("/*/c2s/sessions");
42 local session_registry = {}; 42 local session_registry = {};
43 43
44 local function delayed_ack_function(session) 44 local function delayed_ack_function(session)
45 -- fire event only when configured to do so 45 -- fire event only when configured to do so
46 if delayed_ack_timeout > 0 and session.awaiting_ack and not session.outgoing_stanza_queue == nil then 46 if delayed_ack_timeout > 0 and session.awaiting_ack and not (session.outgoing_stanza_queue == nil) then
47 session.log("debug", "Firing event 'smacks-ack-delayed', queue = %d", #session.outgoing_stanza_queue); 47 session.log("debug", "Firing event 'smacks-ack-delayed', queue = %d", #session.outgoing_stanza_queue);
48 module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue}); 48 module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue});
49 end 49 end
50 session.delayed_ack_timer = nil;
50 end 51 end
51 52
52 local function can_do_smacks(session, advertise_only) 53 local function can_do_smacks(session, advertise_only)
53 if session.smacks then return false, "unexpected-request", "Stream management is already enabled"; end 54 if session.smacks then return false, "unexpected-request", "Stream management is already enabled"; end
54 55
94 session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function() 95 session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function()
95 delayed_ack_function(session); 96 delayed_ack_function(session);
96 end); 97 end);
97 end 98 end
98 end); 99 end);
100 end
101 -- Trigger "smacks-ack-delayed"-event if we added new (ackable) stanzas to the outgoing queue
102 -- and there isn't already a timer for this event running.
103 -- If we wouldn't do this, stanzas added to the queue after the first "smacks-ack-delayed"-event
104 -- would not trigger this event (again).
105 if #queue > max_unacked_stanzas and session.awaiting_ack and session.delayed_ack_timer == nil then
106 session.log("debug", "Calling delayed_ack_function directly (still waiting for ack)");
107 delayed_ack_function(session);
99 end 108 end
100 end 109 end
101 110
102 local function outgoing_stanza_filter(stanza, session) 111 local function outgoing_stanza_filter(stanza, session)
103 local is_stanza = stanza.attr and not stanza.attr.xmlns and not stanza.name:find":"; 112 local is_stanza = stanza.attr and not stanza.attr.xmlns and not stanza.name:find":";
239 if origin.awaiting_ack_timer then 248 if origin.awaiting_ack_timer then
240 origin.awaiting_ack_timer:stop(); 249 origin.awaiting_ack_timer:stop();
241 end 250 end
242 if origin.delayed_ack_timer then 251 if origin.delayed_ack_timer then
243 origin.delayed_ack_timer:stop(); 252 origin.delayed_ack_timer:stop();
253 origin.delayed_ack_timer = nil;
244 end 254 end
245 -- Remove handled stanzas from outgoing_stanza_queue 255 -- Remove handled stanzas from outgoing_stanza_queue
246 log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or ""); 256 log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or "");
247 local h = tonumber(stanza.attr.h); 257 local h = tonumber(stanza.attr.h);
248 if not h then 258 if not h then
428 if session.awaiting_ack_timer then 438 if session.awaiting_ack_timer then
429 session.awaiting_ack_timer:stop(); 439 session.awaiting_ack_timer:stop();
430 end 440 end
431 if session.delayed_ack_timer then 441 if session.delayed_ack_timer then
432 session.delayed_ack_timer:stop(); 442 session.delayed_ack_timer:stop();
443 session.delayed_ack_timer = nil;
433 end 444 end
434 return false; -- Kick the session 445 return false; -- Kick the session
435 end 446 end
436 session.log("debug", "Sending <r> (read timeout)"); 447 session.log("debug", "Sending <r> (read timeout)");
437 session.awaiting_ack = false; 448 session.awaiting_ack = false;