# HG changeset patch # User Kim Alvefur # Date 1645066187 -3600 # Node ID 4f1fe6eb1ddb2645569c50cfd52ea3a9b79d2376 # Parent fb74ff16620cfab4ed2b6a446dcd53ffa1666e79 mod_c2s,mod_s2s: Wait for sessions to close before proceeding with shutdown steps Ensures unavailable presence and other outgoing stanzas are sent. Waiting for c2s sessions to close first before proceeding to disable and close s2s ensures that unavailable presence can go out, even if it requires dialback to complete first. diff -r fb74ff16620c -r 4f1fe6eb1ddb plugins/mod_c2s.lua --- a/plugins/mod_c2s.lua Fri Feb 18 14:25:22 2022 +0100 +++ b/plugins/mod_c2s.lua Thu Feb 17 03:49:47 2022 +0100 @@ -16,7 +16,8 @@ local st = require "util.stanza"; local sm_new_session, sm_destroy_session = sessionmanager.new_session, sessionmanager.destroy_session; local uuid_generate = require "util.uuid".generate; -local runner = require "util.async".runner; +local async = require "util.async"; +local runner = async.runner; local tostring, type = tostring, type; @@ -382,6 +383,7 @@ session.conn = nil; sessions[conn] = nil; end + module:fire_event("c2s-closed", { session = session; conn = conn }); end function listener.onreadtimeout(conn) @@ -431,11 +433,24 @@ end, -80); module:hook("server-stopping", function(event) + local wait, done = async.waiter(); + module:hook("c2s-closed", function () + if next(sessions) == nil then done(); end + end) + -- Close sessions local reason = event.reason; for _, session in pairs(sessions) do session:close{ condition = "system-shutdown", text = reason }; end + + -- Wait for them to close properly if they haven't already + if next(sessions) ~= nil then + add_task(stream_close_timeout+1, done); + module:log("info", "Waiting for sessions to close"); + wait(); + end + end, -100); diff -r fb74ff16620c -r 4f1fe6eb1ddb plugins/mod_s2s.lua --- a/plugins/mod_s2s.lua Fri Feb 18 14:25:22 2022 +0100 +++ b/plugins/mod_s2s.lua Thu Feb 17 03:49:47 2022 +0100 @@ -26,7 +26,8 @@ local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; local uuid_gen = require "util.uuid".generate; -local runner = require "util.async".runner; +local async = require "util.async"; +local runner = async.runner; local connect = require "net.connect".connect; local service = require "net.resolvers.service"; local resolver_chain = require "net.resolvers.chain"; @@ -859,6 +860,7 @@ end s2s_destroy_session(session, err); end + module:fire_event("s2s-closed", { session = session; conn = conn }); end function listener.onfail(data, err) @@ -971,11 +973,24 @@ end end + local wait, done = async.waiter(); + module:hook("s2s-closed", function () + if next(sessions) == nil then done(); end + end, 1) + -- Close sessions local reason = event.reason; for _, session in pairs(sessions) do session:close{ condition = "system-shutdown", text = reason }; end + + -- Wait for them to close properly if they haven't already + if next(sessions) ~= nil then + module:log("info", "Waiting for sessions to close"); + add_task(stream_close_timeout + 1, done); + wait(); + end + end, -200);