Change E2 time quota to be per player#3558
Conversation
I think this would be beneficial for servers, because servers care more about the overall load from a player than about their specific chip. Currently, players can simply spread the load across multiple chips to bypass the quota limit, but this won't eliminate it; it will only increase the overhead
|
I plan to change this to use the average CPU time per player as SF to also get rid of the chip crash during lag spikes. Until then, PR will remain Draft |
…verage load (code from Redox, slightly modified)
|
Looks ok, but I know a lot of people are going to complain about their chips breaking when spawning props for the first time since there's always lag when loading models. Probably should have a pretty lenient average to prevent that. |
|
Like what? The current one is already 0.05 |
|
I mean an average to smooth the spikes. Does e2 already do that somewhere? |
|
I'd suggest a class for cleaner code local PlayerChips = {}
PlayerChips.__index = PlayerChips
function PlayerChips:new() -- static method
return setmetatable({chips = {}}, self)
end
function PlayerChips:getTotalTime()
local total_time = 0
for _, chip in ipairs(self.chips) do
local tab = chip:GetTable()
if tab.error then continue end
local context = tab.context
if not context then continue end
total_time = total_time + context.timebench
end
return total_time
end
function PlayerChips:findMaxTimeChip()
local max_chip, max_time = nil, 0
for _, chip in ipairs(self.chips) do
local tab = chip:GetTable()
if tab.error then continue end
local context = tab.context
if not context then continue end
if context.timebench > max_time then
max_time = context.timebench
max_chip = chip
end
end
return max_chip, max_time
end
function PlayerChips:checkCpuTime()
local total_time = self:getTotalTime()
while total_time > e2_timequota do
local max_chip, max_time = self:findMaxTimeChip()
if max_chip then
total_time = total_time - max_time
max_chip:Error("Expression 2 (" .. max_chip.name .. "): Per-player time quota exceeded", "per-player time quota exceeded")
max_chip:Destruct()
else
-- It shouldn't happen, but if something breaks, it will prevent an infinity loop
break
end
end
end
function PlayerChips:add(chip)
table.insert(self.chips, chip)
end
function PlayerChips:remove(rmchip)
for index, chip in ipairs(self.chips) do
if rmchip == chip then
table.remove(self.chips, index)
break
end
end
end
E2Lib.PlayerChips = setmetatable({},{__index = function(t,ply) local r=PlayerChips:new() t[ply]=r return r end})
hook.Add("Think", "E2_Think", function()
if e2_timequota < 0 then return end
for ply, plychips in pairs(E2Lib.PlayerChips) do
plychips:checkCpuTime()
end
end
end)
-- init.lua
E2Lib.PlayerChips[owner]:add(self) |
|
Also need to make sure that the max_chip:Error and max_chip:Destruct remove the chip from the 'chips' otherwise it'll just keep trying to error the first chip. |
|
|
|
Oh yeah, good point |
Is this really necessary? I don't condemn this approach, but personally, i like when everything is simply in one function |
|
Well, imagine you want to later add an e2 function for total time. It would be good to be able to just use |
|
Probably should add a total time e2function now that e2 chips will need to check it to not error. |
|
I think now everything is ready, i also added the totalCpuUsage function as you said |
I think this would be beneficial for servers, because servers care more about the overall load from a player than about their specific chip. Currently, players can simply spread the load across multiple chips to bypass the quota limit, but this won't eliminate it, it will only increase the overhead
It also turns on E2 disabling by default when disconnecting because it allows to avoids a lot of problems
Thanks Redox/thegrb93 for helping with code