# HG changeset patch # User Kim Alvefur # Date 1723385424 -7200 # Node ID d6a695abb33ce536433f3394b853ae7dd40f0689 # Parent f89367e421d1f652a7b9e9dc6baf522180919802 mod_ping_muc: Delay ping a configurable amount of time If a server is restarting, checking immediately before it has a chance to complete its restart and get ready would often fail, preventing the possibility of transparent restarts as supported by Prosody's mod_muc. Reconnecting immediately when a connection is closed for being idle, or because the remote server is trying to reclaim some resources, is also counter-productive as the connection may fail. Also, if there is some Internet routing problem affecting s2s, it may help to wait a bit before checking, in case the problem resolved itself in the mean time. diff -r f89367e421d1 -r d6a695abb33c mod_ping_muc/mod_ping_muc.lua --- a/mod_ping_muc/mod_ping_muc.lua Wed Aug 07 21:28:11 2024 +0200 +++ b/mod_ping_muc/mod_ping_muc.lua Sun Aug 11 16:10:24 2024 +0200 @@ -28,43 +28,45 @@ for host, state in pairs(s2s_session.hosts) do if state.authed then related_hosts:add(host); end end end - for _, user_session in pairs(local_sessions) do - for _, session in pairs(user_session.sessions) do - if session.rooms_joined then - for room, info in pairs(session.rooms_joined) do - local nick = info.nick or info; - local room_nick = room .. "/" .. nick; - if related_hosts:contains(jid.host(room)) then - -- User is in a MUC room for which the s2s connection was lost. Now what? + local ping_delay = module:get_option_number("ping_muc_delay", 60, 1); + + module:add_timer(ping_delay, function () + for _, user_session in pairs(local_sessions) do + for _, session in pairs(user_session.sessions) do + if session.rooms_joined then + for room, info in pairs(session.rooms_joined) do + local nick = info.nick or info; + local room_nick = room .. "/" .. nick; + if related_hosts:contains(jid.host(room)) then + -- User is in a MUC room for which the s2s connection was lost. Now what? - -- Self-ping - -- ========= - -- - -- Response of means the user is still in the room - -- (and self-ping is supported), so we do nothing. - -- - -- An error reply either means the user has fallen out of the room, - -- or that self-ping is unsupported. In the later case, whether the - -- user is still joined is indeterminate and we might as well - -- pretend they fell out. - module:send_iq(st.iq({ type = "get"; id = id.medium(); from = session.full_jid; to = room_nick }) - :tag("ping", { xmlns = "urn:xmpp:ping"; })) - :catch(function(err) - module:send( - st.presence({ type = "unavailable"; id = id.medium(); to = session.full_jid; from = room_nick }) - :tag("x", { xmlns = "http://jabber.org/protocol/muc#user" }) - :tag("item", { affiliation = "none"; role = "none" }) - :text_tag("reason", err.text or "Connection to remote server lost") - :up() - :tag("status", { code = "110" }):up() - :tag("status", { code = "333" }):up() - :reset()); - end); - -- TODO do this with some delay? + -- Self-ping + -- ========= + -- + -- Response of means the user is still in the room + -- (and self-ping is supported), so we do nothing. + -- + -- An error reply either means the user has fallen out of the room, + -- or that self-ping is unsupported. In the later case, whether the + -- user is still joined is indeterminate and we might as well + -- pretend they fell out. + module:send_iq(st.iq({ type = "get"; id = id.medium(); from = session.full_jid; to = room_nick }) + :tag("ping", { xmlns = "urn:xmpp:ping"; })) + :catch(function(err) + module:send( + st.presence({ type = "unavailable"; id = id.medium(); to = session.full_jid; from = room_nick }) + :tag("x", { xmlns = "http://jabber.org/protocol/muc#user" }) + :tag("item", { affiliation = "none"; role = "none" }) + :text_tag("reason", err.text or "Connection to remote server lost") + :up() + :tag("status", { code = "110" }):up() + :tag("status", { code = "333" }):up() + :reset()); + end); + end end end - end end - end + end) end);