From de15136cfff994953ca5c8da285d07ef5449aadc Mon Sep 17 00:00:00 2001 From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:17:03 -0400 Subject: [PATCH 1/4] Wrap TGS bridge requests so they cannot block reboots forever --- src/DMAPI/tgs/v5/bridge.dm | 39 +++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/DMAPI/tgs/v5/bridge.dm b/src/DMAPI/tgs/v5/bridge.dm index 0c5e701a32b..6f16234d3e8 100644 --- a/src/DMAPI/tgs/v5/bridge.dm +++ b/src/DMAPI/tgs/v5/bridge.dm @@ -79,7 +79,7 @@ TGS_DEBUG_LOG("Bridge request start") // This is an infinite sleep until we get a response - var/export_response = world.Export(bridge_request) + var/export_response = ActuallyPerformBridgeRequest(bridge_request) TGS_DEBUG_LOG("Bridge request complete") if(!export_response) @@ -107,3 +107,40 @@ return return bridge_response + +#define TGS_BRIDGE_WRAP_RETURNED 1 +#define TGS_BRIDGE_WRAP_RESPONSE 2 + +/// world.Export() can hang forever, so we need to give a timeout window. +/datum/tgs_api/v5/proc/ActuallyPerformBridgeRequest(bridge_request) + var/list/bridge_request_tracker = list( + TGS_BRIDGE_WRAP_RETURNED = FALSE, + TGS_BRIDGE_WRAP_RESPONSE = null + ) + + var/start_time = world.time + while(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == FALSE) + if(world.time > (start_time + 30 SECONDS)) // A total of 30 seconds worth of bridge attempts are allowed. + return null + + WrapBridgeRequest(bridge_request, bridge_request_tracker) + // Every bridge attempt gets an initial 5 seconds to respond. + sleep(5 SECONDS) + + if(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == TRUE) + return bridge_request_tracker[TGS_BRIDGE_WRAP_RESPONSE] + +/// Async wrapper around a request, we will poll it later. +/datum/tgs_api/v5/proc/WrapBridgeRequest(bridge_request, list/out) + set waitfor = FALSE + + var/response = world.Export(bridge_request) + // Another bridge request fork responded already. + if(out[TGS_BRIDGE_WRAP_RETURNED]) + return + + out[TGS_BRIDGE_WRAP_RESPONSE] = response + out[TGS_BRIDGE_WRAP_RETURNED] = TRUE + +#undef TGS_BRIDGE_WRAP_RETURNED +#undef TGS_BRIDGE_WRAP_RESPONSE From ad2d84376353927f024613e12f131df0f52bae5e Mon Sep 17 00:00:00 2001 From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:20:29 -0400 Subject: [PATCH 2/4] error log --- src/DMAPI/tgs/v5/bridge.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DMAPI/tgs/v5/bridge.dm b/src/DMAPI/tgs/v5/bridge.dm index 6f16234d3e8..d01c1ebddd3 100644 --- a/src/DMAPI/tgs/v5/bridge.dm +++ b/src/DMAPI/tgs/v5/bridge.dm @@ -121,6 +121,7 @@ var/start_time = world.time while(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == FALSE) if(world.time > (start_time + 30 SECONDS)) // A total of 30 seconds worth of bridge attempts are allowed. + TGS_ERROR_LOG("TGS took too long to respond to a bridge request OR byond couldn't reach TGS.") return null WrapBridgeRequest(bridge_request, bridge_request_tracker) From e1dac6c470781bd7af8124d7ccae4606b3f6465c Mon Sep 17 00:00:00 2001 From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:35:56 -0400 Subject: [PATCH 3/4] check every tick for 10 seconds --- src/DMAPI/tgs/v5/bridge.dm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/DMAPI/tgs/v5/bridge.dm b/src/DMAPI/tgs/v5/bridge.dm index d01c1ebddd3..d8d457dcbe0 100644 --- a/src/DMAPI/tgs/v5/bridge.dm +++ b/src/DMAPI/tgs/v5/bridge.dm @@ -125,8 +125,12 @@ return null WrapBridgeRequest(bridge_request, bridge_request_tracker) - // Every bridge attempt gets an initial 5 seconds to respond. - sleep(5 SECONDS) + var/poll_start_time = world.time + // Every bridge attempt gets an initial 10 seconds to respond. + while(world.time < poll_start_time + 10 SECONDS) + sleep(world.tick_lag) + if(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == TRUE) + return bridge_request_tracker[TGS_BRIDGE_WRAP_RESPONSE] if(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == TRUE) return bridge_request_tracker[TGS_BRIDGE_WRAP_RESPONSE] From 430c25a4d3e3013371036d2b9d72a02ae977a0a9 Mon Sep 17 00:00:00 2001 From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:51:39 -0400 Subject: [PATCH 4/4] remove seconds --- src/DMAPI/tgs/v5/bridge.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DMAPI/tgs/v5/bridge.dm b/src/DMAPI/tgs/v5/bridge.dm index d8d457dcbe0..e868ec11a76 100644 --- a/src/DMAPI/tgs/v5/bridge.dm +++ b/src/DMAPI/tgs/v5/bridge.dm @@ -120,14 +120,14 @@ var/start_time = world.time while(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == FALSE) - if(world.time > (start_time + 30 SECONDS)) // A total of 30 seconds worth of bridge attempts are allowed. + if(world.time > (start_time + 300)) // A total of 30 seconds worth of bridge attempts are allowed. TGS_ERROR_LOG("TGS took too long to respond to a bridge request OR byond couldn't reach TGS.") return null WrapBridgeRequest(bridge_request, bridge_request_tracker) var/poll_start_time = world.time // Every bridge attempt gets an initial 10 seconds to respond. - while(world.time < poll_start_time + 10 SECONDS) + while(world.time < poll_start_time + 100) sleep(world.tick_lag) if(bridge_request_tracker[TGS_BRIDGE_WRAP_RETURNED] == TRUE) return bridge_request_tracker[TGS_BRIDGE_WRAP_RESPONSE]