From 07d3aae9727e81fb6cb36fe00449d7a6527b1f19 Mon Sep 17 00:00:00 2001 From: Amardeep Date: Sat, 30 May 2026 00:43:56 +0530 Subject: [PATCH] host reconnect --- prosody-plugins/mod_politictalk_roles.lua | 65 +++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/prosody-plugins/mod_politictalk_roles.lua b/prosody-plugins/mod_politictalk_roles.lua index 0da0f1d..f3d1e22 100644 --- a/prosody-plugins/mod_politictalk_roles.lua +++ b/prosody-plugins/mod_politictalk_roles.lua @@ -18,6 +18,15 @@ local ROOM_INACTIVE_CALLBACK_SECRET = module:get_option_string( "politictalk_room_inactive_callback_secret", os.getenv("POLITICTALK_ROOM_INACTIVE_CALLBACK_SECRET") ); +local configured_host_reconnect_grace_seconds = module:get_option_string( + "politictalk_host_reconnect_grace_seconds", + os.getenv("POLITICTALK_HOST_RECONNECT_GRACE_SECONDS") +); +local HOST_RECONNECT_GRACE_SECONDS = tonumber(configured_host_reconnect_grace_seconds) or 60; + +if HOST_RECONNECT_GRACE_SECONDS < 5 then + HOST_RECONNECT_GRACE_SECONDS = 5; +end local function derive_room_occupancy_callback_url(inactive_url) if not inactive_url or inactive_url == "" then @@ -169,6 +178,8 @@ local function mark_host(room, occupant, user_id) room._data.politictalk_host_jids = add_unique(room._data.politictalk_host_jids, occupant.bare_jid); room._data.politictalk_participant_jids = remove_value(room._data.politictalk_participant_jids, occupant.bare_jid); room._data.politictalk_jid_user_ids[occupant.bare_jid] = user_id; + room._data.politictalk_host_left_destroy_token = nil; + room._data.politictalk_host_left_destroy_at = nil; end local function mark_participant(room, occupant, user_id) @@ -469,6 +480,54 @@ local function notify_room_occupancy(room, reason) end); end +local function schedule_room_destroy_after_host_left(room) + if not room then + return; + end + + ensure_room_data(room); + + local token = (room._data.politictalk_host_left_destroy_token or 0) + 1; + room._data.politictalk_host_left_destroy_token = token; + room._data.politictalk_host_left_destroy_at = os.time() + HOST_RECONNECT_GRACE_SECONDS; + + module:log( + "info", + "Scheduling PoliticTalk room destroy after host reconnect grace: room=%s grace=%ss token=%s", + tostring(room.jid), + tostring(HOST_RECONNECT_GRACE_SECONDS), + tostring(token) + ); + + notify_room_occupancy(room, "host_reconnect_pending"); + + module:add_timer(HOST_RECONNECT_GRACE_SECONDS, function() + if not room or not room._data then + return; + end + + ensure_room_data(room); + + if room._data.politictalk_host_left_destroy_token ~= token then + return; + end + + if has_active_host(room) then + room._data.politictalk_host_left_destroy_token = nil; + room._data.politictalk_host_left_destroy_at = nil; + notify_room_occupancy(room, "host_reconnected"); + return; + end + + room._data.politictalk_host_left_destroy_token = nil; + room._data.politictalk_host_left_destroy_at = nil; + + module:log("info", "Destroying PoliticTalk room after host reconnect grace expired: %s", tostring(room.jid)); + notify_room_inactive(room, "host_left"); + room:destroy(nil, "The host has left the PoliticTalk room"); + end); +end + module:hook("muc-room-pre-create", function(event) if event.stanza and event.stanza.attr and is_admin(event.stanza.attr.from) then return; @@ -585,9 +644,7 @@ module:hook("muc-occupant-left", function(event) end if was_host and not has_active_host(room) then - module:log("info", "Destroying PoliticTalk room after host left: %s", tostring(room.jid)); - notify_room_inactive(room, "host_left"); - room:destroy(nil, "The host has left the PoliticTalk room"); + schedule_room_destroy_after_host_left(room); else notify_room_occupancy(room, "occupant_left"); end @@ -597,6 +654,8 @@ module:hook("muc-room-destroyed", function(event) local room = event.room; if room and room._data and room._data.politictalk_host_jids then + room._data.politictalk_host_left_destroy_token = nil; + room._data.politictalk_host_left_destroy_at = nil; notify_room_inactive(room, "room_destroyed"); end end, -30);