Mercurial > prosody-modules
changeset 2491:5fbca7de2088
mod_smacks: Send out more ack requests where needed
Under some circumstances it was possible that more than "max_unacked_stanzas"
where left in the outgoing stanza queue without forcing an ack.
This could happen, when more stanzas entered the queue while the last ack request
was still unanswered.
Now the test "#queue > max_unacked_stanzas" is done upon receiving
an ack as well as when sending out stanzas, which fixes this bug.
author | tmolitor <thilo@eightysoft.de> |
---|---|
date | Sun, 12 Feb 2017 19:27:50 +0100 (2017-02-12) |
parents | 85509650ba82 |
children | 63fb612d6ec5 d300ae5dba87 |
files | mod_smacks/mod_smacks.lua |
diffstat | 1 files changed, 23 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_smacks/mod_smacks.lua Fri Feb 10 22:50:45 2017 +0100 +++ b/mod_smacks/mod_smacks.lua Sun Feb 12 19:27:50 2017 +0100 @@ -5,7 +5,7 @@ -- Copyright (C) 2012-2015 Kim Alvefur -- Copyright (C) 2012 Thijs Alkemade -- Copyright (C) 2014 Florian Zeitz --- Copyright (C) 2016 Thilo Molitor +-- Copyright (C) 2016-2017 Thilo Molitor -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. @@ -80,6 +80,25 @@ end end); +local function request_ack_if_needed(session) + local queue = session.outgoing_stanza_queue; + if #queue > max_unacked_stanzas and session.awaiting_ack == nil then + session.log("debug", "Queuing <r> (in a moment)"); + session.awaiting_ack = false; + session.awaiting_ack_timer = module:add_timer(1e-06, function () + if not session.awaiting_ack then + session.log("debug", "Sending <r> (inside timer, before send)"); + (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks })) + session.log("debug", "Sending <r> (inside timer, after send)"); + session.awaiting_ack = true; + session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function() + delayed_ack_function(session); + end); + end + end); + end +end + local function outgoing_stanza_filter(stanza, session) local is_stanza = stanza.attr and not stanza.attr.xmlns and not stanza.name:find":"; if is_stanza and not stanza._cached then -- Stanza in default stream namespace @@ -97,21 +116,7 @@ session.log("debug", "hibernating, stanza queued"); return nil; end - if #queue > max_unacked_stanzas and session.awaiting_ack == nil then - session.log("debug", "Queuing <r> (in a moment)"); - session.awaiting_ack = false; - session.awaiting_ack_timer = module:add_timer(1e-06, function () - if not session.awaiting_ack then - session.log("debug", "Sending <r> (before send)"); - (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks })) - session.log("debug", "Sending <r> (after send)"); - session.awaiting_ack = true; - session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function() - delayed_ack_function(session); - end); - end - end); - end + request_ack_if_needed(session); end return stanza; end @@ -238,7 +243,7 @@ origin.delayed_ack_timer:stop(); end -- Remove handled stanzas from outgoing_stanza_queue - --log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or ""); + log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or ""); local h = tonumber(stanza.attr.h); if not h then origin:close{ condition = "invalid-xml"; text = "Missing or invalid 'h' attribute"; }; @@ -258,6 +263,7 @@ end origin.log("debug", "#queue = %d", #queue); origin.last_acknowledged_stanza = origin.last_acknowledged_stanza + handled_stanza_count; + request_ack_if_needed(origin) return true; end module:hook_stanza(xmlns_sm2, "a", handle_a);