diff mod_ping_muc/mod_ping_muc.lua @ 5951:d6a695abb33c

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.
author Kim Alvefur <zash@zash.se>
date Sun, 11 Aug 2024 16:10:24 +0200
parents 0772facc786f
children
line wrap: on
line diff
--- 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 <iq type=result> 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 <iq type=result> 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);