aboutsummaryrefslogtreecommitdiff
path: root/circuit_breaker.lua
diff options
context:
space:
mode:
authorNatureFreshMilk <naturefreshmilk@github.com>2019-09-10 07:25:03 +0200
committerNatureFreshMilk <naturefreshmilk@github.com>2019-09-10 07:25:03 +0200
commit9ce2af3c0d464fc526b2036d66cc86e989dc71e3 (patch)
tree04b045a1828b7b55232713ca6953fd5a91688dcd /circuit_breaker.lua
parentae937581e7167e2d6e9444b6ac2cd00bf2e2beca (diff)
downloadmesecons_debug-9ce2af3c0d464fc526b2036d66cc86e989dc71e3.tar.gz
mesecons_debug-9ce2af3c0d464fc526b2036d66cc86e989dc71e3.zip
Revert "embedded smart actionqueue"
This reverts commit 0941f6726b67669173c524302cf006c365895179.
Diffstat (limited to 'circuit_breaker.lua')
-rw-r--r--circuit_breaker.lua138
1 files changed, 138 insertions, 0 deletions
diff --git a/circuit_breaker.lua b/circuit_breaker.lua
new file mode 100644
index 0000000..ce1452a
--- /dev/null
+++ b/circuit_breaker.lua
@@ -0,0 +1,138 @@
+
+-- "circuit break" mapblocks in which mesecons took too long to execute
+-- TODO: toggleable hud with current cpu usage
+
+-- sample/reset interval
+local sample_interval = 10
+
+-- util
+-- minetest.hash_node_position(get_blockpos(pos))
+local function get_blockpos(pos)
+ return {x = math.floor(pos.x / 16),
+ y = math.floor(pos.y / 16),
+ z = math.floor(pos.z / 16)}
+end
+
+
+-- per block cpu time usage in micros
+local per_block_time_usage = {}
+
+-- max per block cpu time usage in micros
+local max_per_block_time_usage = {}
+
+-- disabled/dark mapblocks
+local dark_mapblocks = {}
+
+-- switch off setting
+local max_time_setting
+local dark_time
+
+function update_settings()
+ max_time_setting = tonumber( minetest.settings:get("mesecons_debug.circuit_breaker") or "75000" )
+ dark_time = tonumber( minetest.settings:get("mesecons_debug.dark_time") or "30000000" )
+end
+
+update_settings()
+
+-- periodic timer
+local timer = 0
+minetest.register_globalstep(function(dtime)
+ timer = timer + dtime
+ if timer < sample_interval then return end
+ timer=0
+
+ -- reset time usage
+ per_block_time_usage = {}
+
+ -- update settings, if changed
+ update_settings()
+
+end)
+
+-- mesecon mod overrides
+local old_execute = mesecon.queue.execute
+mesecon.queue.execute = function(self, action)
+ local blockpos = get_blockpos(action.pos)
+ local hash = minetest.hash_node_position(blockpos)
+ local t0 = minetest.get_us_time()
+
+ local dark_timer = dark_mapblocks[hash]
+ if dark_timer and dark_timer < t0 then
+ -- timeout expired, disable mapblock throttling
+ dark_mapblocks[hash] = nil
+ dark_timer = nil
+ end
+
+ local time_usage = per_block_time_usage[hash] or 0
+
+ old_execute(self, action)
+ local t1 = minetest.get_us_time()
+ local diff = t1 -t0
+ time_usage = time_usage + diff
+
+ -- update max stats
+ if (max_per_block_time_usage[hash] or 0) < time_usage then
+ max_per_block_time_usage[hash] = time_usage
+ end
+
+ if time_usage > max_time_setting and not dark_timer then
+ -- time usage exceeded, throttle mapblock
+ dark_mapblocks[hash] = t1 + dark_time
+ minetest.log("warning", "[mesecons_debug] throttled mapblock at " ..
+ minetest.pos_to_string(action.pos))
+ end
+
+ -- update time usage
+ per_block_time_usage[hash] = time_usage
+end
+
+local old_add_action = mesecon.queue.add_action
+mesecon.queue.add_action = function(self, pos, func, params, time, overwritecheck, priority)
+ time = time or 0
+ local blockpos = get_blockpos(pos)
+ local hash = minetest.hash_node_position(blockpos)
+
+ local dark_timer = dark_mapblocks[hash]
+ if dark_timer then
+ -- throttle add actions
+ time = time + 1
+ end
+
+ old_add_action(self, pos, func, params, time, overwritecheck, priority)
+end
+
+
+-- chat commands
+
+minetest.register_chatcommand("mesecons_debug_circuit_breaker_stats", {
+ description = "shows the stats for the current mapblock",
+ func = function(name)
+ local player = minetest.get_player_by_name(name)
+ local pos = player:get_pos()
+ local blockpos = get_blockpos(pos)
+ local hash = minetest.hash_node_position(blockpos)
+ local time_usage = max_per_block_time_usage[hash] or 0
+
+ local t0 = minetest.get_us_time()
+ local dark_timer = dark_mapblocks[hash]
+
+ local msg = "Max-time usage: " .. time_usage .. " micro-seconds " ..
+ "(sampled over " .. sample_interval .. " seconds)"
+
+ if dark_timer and dark_timer > t0 then
+ msg = msg .. " [Mapblock throttled!]"
+ end
+
+ return true, msg
+ end
+})
+
+minetest.register_chatcommand("mesecons_debug_circuit_breaker_stats_reset", {
+ description = "resets the max stats",
+ privs = {mesecons_debug=true},
+ func = function()
+ max_per_block_time_usage = {}
+ dark_mapblocks = {}
+ return true, "circuit breaker stats cleared!"
+ end
+})