diff options
author | BuckarooBanzay <BuckarooBanzay@users.noreply.github.com> | 2021-03-14 21:21:37 +0100 |
---|---|---|
committer | BuckarooBanzay <BuckarooBanzay@users.noreply.github.com> | 2021-03-14 21:21:37 +0100 |
commit | fdb69489d823d3cb22f9757732245958f9734f3a (patch) | |
tree | faede629dfe505d68fd8dafc532d47caa492b41c | |
parent | 40ecd2db7223d178de6d21807499ff17ad3cf2ce (diff) | |
download | mesecons_debug-fdb69489d823d3cb22f9757732245958f9734f3a.tar.gz mesecons_debug-fdb69489d823d3cb22f9757732245958f9734f3a.zip |
rework penalty stuff
addresses some issues in #6
-rw-r--r-- | clear_penalty.lua | 29 | ||||
-rw-r--r-- | context.lua | 53 | ||||
-rw-r--r-- | init.lua | 12 | ||||
-rw-r--r-- | overrides.lua | 4 | ||||
-rw-r--r-- | penalty.lua | 60 |
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) @@ -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) |