From 59762d4207a4eff0e453614a20450ae4c557ec6d Mon Sep 17 00:00:00 2001 From: Ren Erthilo Date: Wed, 2 May 2012 21:39:41 +0100 Subject: [PATCH] TG: An attempt to make the master controller more robust. This shouldn't cause terrible additional lag, given that the master controller doesn't actually fire that often, and can also give us a clue as to what part of the controller has died in case of failure Modifies do_after to something that fires a lot less, and is hopefully more robust against infinite loops. It is now theoretically possible to run around and then come back to the same place and have it complete, but that's only really valid for extremely long times (like handcuff removal) and if you get lucky and dodge one of the timed checks. Revision: r3421 Author: VivianFoxfoot --- code/game/cellautomata.dm | 3 +- code/game/master_controller.dm | 148 +++++++++++++++++++++++++----- code/modules/admin/admin_verbs.dm | 3 +- code/modules/admin/verbs/MC.dm | 12 +++ code/modules/mob/mob.dm | 4 +- 5 files changed, 143 insertions(+), 27 deletions(-) diff --git a/code/game/cellautomata.dm b/code/game/cellautomata.dm index 3f878ecdfae..5bf3b888a55 100644 --- a/code/game/cellautomata.dm +++ b/code/game/cellautomata.dm @@ -125,7 +125,8 @@ src.update_status() master_controller = new /datum/controller/game_controller() - spawn(-1) master_controller.setup() + spawn(-1) + master_controller.setup() return //Crispy fullban diff --git a/code/game/master_controller.dm b/code/game/master_controller.dm index 8128b4c7a98..175bbc62aa0 100644 --- a/code/game/master_controller.dm +++ b/code/game/master_controller.dm @@ -1,9 +1,26 @@ var/global/datum/controller/game_controller/master_controller //Set in world.New() +var/global/datum/failsafe/Failsafe var/global/controllernum = "no" +var/global/controller_iteration = 0 + + + + datum/controller/game_controller var/processing = 1 + var/global/air_master_ready = 0 + var/global/tension_master_ready = 0 + var/global/sun_ready = 0 + var/global/mobs_ready = 0 + var/global/diseases_ready = 0 + var/global/machines_ready = 0 + var/global/objects_ready = 0 + var/global/networks_ready = 0 + var/global/powernets_ready = 0 + var/global/ticker_ready = 0 + proc setup() setup_objects() @@ -80,57 +97,142 @@ datum/controller/game_controller process() + if(!Failsafe) + Failsafe = new /datum/failsafe + spawn(0) + Failsafe.spin() + + if(!processing) return 0 controllernum = "yes" - spawn (100) controllernum = "no" + spawn (100) + controllernum = "no" + + controller_iteration++ var/start_time = world.timeofday - air_master.process() + air_master_ready = 0 + tension_master_ready = 0 + sun_ready = 0 + mobs_ready = 0 + diseases_ready = 0 + machines_ready = 0 + objects_ready = 0 + networks_ready = 0 + powernets_ready = 0 + ticker_ready = 0 - tension_master.process() + + + + + spawn(0) + air_master.process() + air_master_ready = 1 + spawn(0) + tension_master.process() + tension_master_ready = 1 sleep(1) - sun.calc_position() + spawn(0) + sun.calc_position() + sun_ready = 1 sleep(-1) - for(var/mob/M in world) - M.Life() + spawn(0) + for(var/mob/M in world) + M.Life() + mobs_ready = 1 + + sleep(-1) - for(var/datum/disease/D in active_diseases) - D.process() + spawn(0) + for(var/datum/disease/D in active_diseases) + D.process() + diseases_ready = 1 - for(var/obj/machinery/machine in machines) - if(machine) - machine.process() - if(machine && machine.use_power) - machine.auto_use_power() + spawn(0) + for(var/obj/machinery/machine in machines) + if(machine) + machine.process() + if(machine && machine.use_power) + machine.auto_use_power() + machines_ready = 1 sleep(-1) sleep(1) - for(var/obj/object in processing_objects) - object.process() + spawn(0) + for(var/obj/object in processing_objects) + object.process() + objects_ready = 1 - for(var/datum/pipe_network/network in pipe_networks) - network.process() + spawn(0) + for(var/datum/pipe_network/network in pipe_networks) + network.process() + networks_ready = 1 - for(var/datum/powernet/P in powernets) - P.reset() + spawn(0) + for(var/datum/powernet/P in powernets) + P.reset() + powernets_ready = 1 sleep(-1) - ticker.process() + spawn(0) + ticker.process() + ticker_ready = 1 - sleep(world.timeofday+10-start_time) // This is fine for our tick lag. DMTG + sleep(world.timeofday+10-start_time)// Don't touch this. DMTG - spawn process() + while(!air_master_ready || !tension_master_ready || !sun_ready || !mobs_ready || !diseases_ready || !machines_ready || !objects_ready || !networks_ready || !powernets_ready || !ticker_ready) + sleep(1) + + spawn + process() - return 1 \ No newline at end of file + return 1 + + + +/datum/failsafe // This thing pretty much just keeps poking the master controller + var/spinning = 1 + var/current_iteration = 0 + +/datum/failsafe/proc/spin() + if(!master_controller) // Well fuck. How did this happen? + sleep(50) + if(!master_controller) + master_controller = new /datum/controller/game_controller() + spawn(-1) + master_controller.setup() + + else + while(spinning) + current_iteration = controller_iteration + sleep(600) // Wait 15 seconds + if(current_iteration == controller_iteration) // Mm. The master controller hasn't ticked yet. + + for (var/mob/M in world) + if (M.client && M.client.holder) + M << " Warning. The Master Controller has not fired in the last 60 seconds. Restart recommended. Automatic restart in 60 seconds." + + sleep(600) + if(current_iteration == controller_iteration) + for (var/mob/M in world) + if (M.client && M.client.holder) + M << " Warning. The Master Controller has not fired in the last 2 minutes. Automatic restart beginning." + master_controller.process() + sleep(150) + else + for (var/mob/M in world) + if (M.client && M.client.holder) + M << " The Master Controller has fired. Automatic restart aborted." \ No newline at end of file diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index ae551810a05..38e63dea1b0 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -227,7 +227,7 @@ //verbs += /proc/togglebuildmode --Merged with view variables //verbs += /client/proc/cmd_modify_object_variables --Merged with view variables verbs += /client/proc/togglebuildmodeself - + verbs += /client/proc/debug_master_controller else return //Game Admin @@ -445,6 +445,7 @@ //verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying verbs -= /client/proc/togglebuildmodeself verbs -= /client/proc/kill_airgroup + verbs -= /client/proc/debug_master_controller verbs -= /client/proc/admin_deny_shuttle verbs -= /client/proc/cmd_admin_christmas verbs -= /client/proc/editappear diff --git a/code/modules/admin/verbs/MC.dm b/code/modules/admin/verbs/MC.dm index ded7740c2c1..a9481f7f348 100644 --- a/code/modules/admin/verbs/MC.dm +++ b/code/modules/admin/verbs/MC.dm @@ -7,4 +7,16 @@ master_controller.process() if("No") return 0 + //feedback_add_details("admin_verb","RMC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + +/client/proc/debug_master_controller() + set category = "Debug" + set name = "Debug Master Controller" + switch(alert("Debug Master Controller or Failsafe?" ,, "Master Controller" , "Failsafe")) + if("Master Controller") + debug_variables(master_controller) + if("Failsafe") + debug_variables(Failsafe) + //feedback_add_details("admin_verb","DMC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f3355dba7f7..ca7176b713d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1038,8 +1038,8 @@ note dizziness decrements automatically in the mob's Life() proc. stat(null, "([x], [y], [z])") stat(null, "CPU: [world.cpu]") stat(null, "Controller: [controllernum]") - //if (master_controller) - // stat(null, "Loop: [master_controller.loop_freq]") + if (master_controller) + stat(null, "Current Iteration: [controller_iteration]") if (spell_list.len)