aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBuckarooBanzay <BuckarooBanzay@users.noreply.github.com>2021-03-14 21:21:37 +0100
committerBuckarooBanzay <BuckarooBanzay@users.noreply.github.com>2021-03-14 21:21:37 +0100
commitfdb69489d823d3cb22f9757732245958f9734f3a (patch)
treefaede629dfe505d68fd8dafc532d47caa492b41c
parent40ecd2db7223d178de6d21807499ff17ad3cf2ce (diff)
downloadmesecons_debug-fdb69489d823d3cb22f9757732245958f9734f3a.tar.gz
mesecons_debug-fdb69489d823d3cb22f9757732245958f9734f3a.zip
rework penalty stuff
addresses some issues in #6
-rw-r--r--clear_penalty.lua29
-rw-r--r--context.lua53
-rw-r--r--init.lua12
-rw-r--r--overrides.lua4
-rw-r--r--penalty.lua60
5 files changed, 106 insertions, 52 deletions
diff --git a/clear_penalty.lua b/clear_penalty.lua
new file mode 100644
index 0000000..f89e8fc
--- /dev/null
+++ b/clear_penalty.lua
@@ -0,0 +1,29 @@
+
+-- playername => time-of-last-cooldown
+local cooldown = {}
+
+minetest.register_chatcommand("mesecons_clear_penalty", {
+ description = "clears the penalty in the current mapblock " ..
+ "(cooldown: " .. mesecons_debug.penalty_clear_cooldown .. ")",
+ func = function(name)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return
+ end
+
+ local last_cooldown_time = cooldown[name] or 0
+ local remaining_time = mesecons_debug.penalty_clear_cooldown - (os.time() - last_cooldown_time)
+ if remaining_time > 0 then
+ -- cooldown still in progress
+ return true, "cooldown still in progress, remaining time: " .. remaining_time .. " seconds"
+ end
+
+ -- set timer
+ cooldown[name] = os.time()
+
+ local ctx = mesecons_debug.get_context(player:get_pos())
+ ctx.penalty = 0
+
+ return true, "penalty reset"
+ end
+})
diff --git a/context.lua b/context.lua
index 7e70c1c..cf9b343 100644
--- a/context.lua
+++ b/context.lua
@@ -1,12 +1,5 @@
-local has_monitoring = minetest.get_modpath("monitoring")
-
-local mapblock_count, penalized_mapblock_count
-
-if has_monitoring then
- mapblock_count = monitoring.gauge("mesecons_debug_mapblock_count", "count of tracked mapblocks")
- penalized_mapblock_count = monitoring.gauge("mesecons_debug_penalized_mapblock_count", "count of penalized mapblocks")
-end
+-- returns the context data for the node-position
mesecons_debug.get_context = function(pos)
local blockpos = mesecons_debug.get_blockpos(pos)
local hash = minetest.hash_node_position(blockpos)
@@ -35,47 +28,3 @@ mesecons_debug.get_context = function(pos)
return ctx
end
-
-local timer = 0
-minetest.register_globalstep(function(dtime)
- timer = timer + dtime
- if timer < 1 then return end
- timer=0
-
- local penalized_count = 0
- local now = minetest.get_us_time()
- local cleanup_time_micros = 300 * 1000 * 1000
-
- mesecons_debug.context_store_size = 0
- for hash, ctx in pairs(mesecons_debug.context_store) do
- local time_diff = now - ctx.mtime
- if time_diff > cleanup_time_micros then
- -- remove item
- mesecons_debug.context_store[hash] = nil
-
- else
- -- calculate stuff
- ctx.avg_micros = math.floor((ctx.avg_micros * 0.9) + (ctx.micros * 0.1))
- ctx.micros = 0
- if ctx.avg_micros > mesecons_debug.max_usage_micros then
- -- add penalty
- ctx.penalty = math.min(ctx.penalty + 0.1, 20)
- elseif ctx.penalty > 0 then
- -- remove penalty (slowly)
- ctx.penalty = math.max(ctx.penalty - 0.01, 0)
- end
-
- mesecons_debug.context_store_size = mesecons_debug.context_store_size + 1
- if ctx.penalty > 0 then
- penalized_count = penalized_count + 1
- end
-
- end
- end
-
- if has_monitoring then
- mapblock_count.set(mesecons_debug.context_store_size)
- penalized_mapblock_count.set(penalized_count)
- end
-
-end)
diff --git a/init.lua b/init.lua
index a359583..64ce185 100644
--- a/init.lua
+++ b/init.lua
@@ -6,12 +6,22 @@ mesecons_debug = {
context_store = {},
context_store_size = 0,
+ -- max penalty in seconds
+ max_penalty = 300,
+
+ -- everything above this threshold will disable the mesecons in that mapblock
+ penalty_mapblock_disabled = 60,
+
+ -- time between /mesecons_clear_penalty commands, in seconds
+ penalty_clear_cooldown = 120,
+
-- mapblock-hash -> true
whitelist = {},
-- playername => true
hud = {},
+ -- cpu usage in microseconds that triggers the penalty mechanism
max_usage_micros = 15000
}
@@ -20,6 +30,8 @@ dofile(MP.."/whitelist.lua")
dofile(MP.."/privs.lua")
dofile(MP.."/flush.lua")
dofile(MP.."/context.lua")
+dofile(MP.."/penalty.lua")
+dofile(MP.."/clear_penalty.lua")
dofile(MP.."/overrides.lua")
dofile(MP.."/luacontroller.lua")
dofile(MP.."/chatcommands.lua")
diff --git a/overrides.lua b/overrides.lua
index 21bf3b2..55e480b 100644
--- a/overrides.lua
+++ b/overrides.lua
@@ -25,6 +25,10 @@ mesecon.queue.add_action = function(self, pos, func, params, time, overwritechec
time = time or 0
time = time + ctx.penalty
+ if time > mesecons_debug.penalty_mapblock_disabled then
+ -- penalty exceeded disable-threshold, don't even add the action
+ return
+ end
old_add_action(self, pos, func, params, time, overwritecheck, priority)
--print("add_action() pos=" .. minetest.pos_to_string(pos))
diff --git a/penalty.lua b/penalty.lua
new file mode 100644
index 0000000..b7173b7
--- /dev/null
+++ b/penalty.lua
@@ -0,0 +1,60 @@
+local has_monitoring = minetest.get_modpath("monitoring")
+
+local mapblock_count, penalized_mapblock_count
+
+if has_monitoring then
+ mapblock_count = monitoring.gauge("mesecons_debug_mapblock_count", "count of tracked mapblocks")
+ penalized_mapblock_count = monitoring.gauge("mesecons_debug_penalized_mapblock_count", "count of penalized mapblocks")
+end
+
+local timer = 0
+minetest.register_globalstep(function(dtime)
+ timer = timer + dtime
+ if timer < 1 then return end
+ timer=0
+
+ local penalized_count = 0
+ local now = minetest.get_us_time()
+ local cleanup_time_micros = 300 * 1000 * 1000
+
+ mesecons_debug.context_store_size = 0
+ for hash, ctx in pairs(mesecons_debug.context_store) do
+ local time_diff = now - ctx.mtime
+ if time_diff > cleanup_time_micros then
+ -- remove item
+ mesecons_debug.context_store[hash] = nil
+
+ else
+ -- calculate moving average
+ ctx.avg_micros = math.floor((ctx.avg_micros * 0.8) + (ctx.micros * 0.2))
+ -- reset cpu usage counter
+ ctx.micros = 0
+
+ -- apply penalty values
+ if ctx.avg_micros > (mesecons_debug.max_usage_micros * 10) then
+ -- 10 times the limit used, potential abuse, add a greater penalty value
+ ctx.penalty = math.min(ctx.penalty + 5, mesecons_debug.max_penalty)
+
+ elseif ctx.avg_micros > mesecons_debug.max_usage_micros then
+ -- add penalty value
+ ctx.penalty = math.min(ctx.penalty + 0.2, mesecons_debug.max_penalty)
+
+ elseif ctx.penalty > 0 then
+ -- remove penalty (very slowly)
+ ctx.penalty = math.max(ctx.penalty - 0.001, 0)
+ end
+
+ mesecons_debug.context_store_size = mesecons_debug.context_store_size + 1
+ if ctx.penalty > 0 then
+ penalized_count = penalized_count + 1
+ end
+
+ end
+ end
+
+ if has_monitoring then
+ mapblock_count.set(mesecons_debug.context_store_size)
+ penalized_mapblock_count.set(penalized_count)
+ end
+
+end)