Failsafe added to the debug/restart controller verbs.dm

Failsafe now checks the lighting_controller too. It will restart it if it doesn't progress for 5 cycles (same as MC)
datum/failsafe is now datum/controller/failsafe

The probability of lights breaking after spawn was reduced from tube:10 and bulb:25 to tube:2 bulb:5

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4674 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
elly1989@rocketmail.com
2012-09-10 12:53:55 +00:00
parent e1bdd57bf2
commit 9f1362c68d
5 changed files with 85 additions and 283 deletions

View File

@@ -0,0 +1,72 @@
var/datum/controller/failsafe/Failsafe
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
var/processing = 0
var/processing_interval = 100 //poke the MC every 10 seconds
var/MC_iteration = 0
var/MC_defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one)
var/lighting_iteration = 0
var/lighting_defcon = 0 //alert level for lighting controller.
/datum/controller/failsafe/New()
//There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one)
if(Failsafe != src)
if(istype(Failsafe))
del(Failsafe)
Failsafe = src
Failsafe.process()
/datum/controller/failsafe/proc/process()
processing = 1
spawn(0)
set background = 1
while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop
if(!master_controller) new /datum/controller/game_controller() //replace the missing master_controller! This should never happen.
if(!lighting_controller) new /datum/controller/lighting() //replace the missing lighting_controller
if(processing)
if(master_controller.processing) //only poke if these overrides aren't in effect
if(MC_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval
switch(MC_defcon)
if(0 to 3)
MC_defcon++
if(4)
for(var/client/C in admin_list)
C << "<font color='red' size='2'><b>Warning. The Master Controller has not fired in the last [MC_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
MC_defcon = 5
if(5)
for(var/client/C in admin_list)
C << "<font color='red' size='2'><b>Warning. The Master Controller has still not fired within the last [MC_defcon*processing_interval] ticks. Killing and restarting...</b></font>"
new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process)
master_controller.process() //Start it rolling again
MC_defcon = 0
else
MC_defcon = 0
MC_iteration = controller_iteration
if(lighting_controller.processing)
if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval
switch(lighting_defcon)
if(0 to 3)
lighting_defcon++
if(4)
for(var/client/C in admin_list)
C << "<font color='red' size='2'><b>Warning. The Lighting Controller has not fired in the last [lighting_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
lighting_defcon = 5
if(5)
for(var/client/C in admin_list)
C << "<font color='red' size='2'><b>Warning. The Lighting Controller has still not fired within the last [lighting_defcon*processing_interval] ticks. Killing and restarting...</b></font>"
new /datum/controller/lighting() //replace the old lighting_controller (hence killing the old one's process)
lighting_controller.process() //Start it rolling again
lighting_defcon = 0
else
lighting_defcon = 0
lighting_iteration = lighting_controller.iteration
else
MC_defcon = 0
lighting_defcon = 0
sleep(processing_interval)

View File

@@ -3,7 +3,6 @@
//WIP, needs lots of work still
var/global/datum/controller/game_controller/master_controller //Set in world.New()
var/global/datum/failsafe/Failsafe
var/global/controller_iteration = 0
var/global/last_tick_timeofday = world.timeofday
@@ -30,7 +29,7 @@ datum/controller/game_controller
datum/controller/game_controller/New()
//There can be only one master_controller. Out with the old and in with the new.
if(master_controller != src)
if(istype(master_controller,/datum/controller/game_controller))
if(istype(master_controller))
Recover()
del(master_controller)
master_controller = src
@@ -97,7 +96,7 @@ datum/controller/game_controller/proc/process()
spawn(0)
set background = 1
while(1) //far more efficient than recursively calling ourself
if(!Failsafe) new /datum/failsafe()
if(!Failsafe) new /datum/controller/failsafe()
var/currenttime = world.timeofday
last_tick_duration = (currenttime - last_tick_timeofday) / 10
@@ -247,65 +246,3 @@ datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
msg += "\t [varname] = [varval]\n"
world.log << msg
/datum/failsafe // This thing pretty much just keeps poking the master controller
var/spinning = 1
var/current_iteration = 0
var/ticks_per_spin = 100 //poke the MC every 10 seconds
var/defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one)
/datum/failsafe/New()
//There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one)
if(Failsafe && (Failsafe != src))
del(Failsafe)
Failsafe = src
current_iteration = controller_iteration
Failsafe.spin()
/datum/failsafe/proc/spin()
spawn(0)
set background = 1
while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop
if(master_controller)
if(spinning && master_controller.processing) //only poke if these overrides aren't in effect
if(current_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval
switch(defcon)
if(0 to 3)
defcon++
if(4)
for(var/client/C in admin_list)
if(C.holder)
C << "<font color='red' size='2'><b>Warning. The Master Controller has not fired in the last [defcon*ticks_per_spin] ticks. Automatic restart in [ticks_per_spin] ticks.</b></font>"
defcon = 5
if(5)
for(var/client/C in admin_list)
if(C.holder)
C << "<font color='red' size='2'><b>Warning. The Master Controller has still not fired within the last [defcon*ticks_per_spin] ticks. Killing and restarting...</b></font>"
new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process)
master_controller.process() //Start it rolling again
defcon = 0
else
defcon = 0
current_iteration = controller_iteration
else
defcon = 0
else
new /datum/controller/game_controller() //replace the missing master_controller! This should never happen.
sleep(ticks_per_spin)
//DEBUG VERBS
/*
/client/verb/spawn_MC()
new /datum/controller/game_controller()
/client/verb/spawn_FS()
new /datum/failsafe()
/client/verb/machines_list()
for(var/i=1,i<=machines.len,i++)
var/machine = machines[i]
if(istype(machine,/datum)) world.log << machine:type
else world.log << machine
*/

View File

@@ -1,7 +1,7 @@
//TODO: rewrite and standardise all controller datums to the datum/controller type
//TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done
/client/proc/restart_controller(controller in list("Master","Lighting","Supply Shuttle"))
/client/proc/restart_controller(controller in list("Master","Failsafe","Lighting","Supply Shuttle"))
set category = "Debug"
set name = "Restart Controller"
set desc = "Restart one of the various periodic loop controllers for the game (be careful!)"
@@ -14,6 +14,9 @@
new /datum/controller/game_controller()
master_controller.process()
feedback_add_details("admin_verb","RMC")
if("Failsafe")
new /datum/controller/failsafe()
feedback_add_details("admin_verb","RFailsafe")
if("Lighting")
new /datum/controller/lighting()
lighting_controller.process()
@@ -25,7 +28,7 @@
return
/client/proc/debug_controller(controller in list("Master","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI"))
/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -35,6 +38,9 @@
if("Master")
debug_variables(master_controller)
feedback_add_details("admin_verb","DMC")
if("Failsafe")
debug_variables(Failsafe)
feedback_add_details("admin_verb","DFailsafe")
if("Ticker")
debug_variables(ticker)
feedback_add_details("admin_verb","DTicker")