From 6ca21fcae6d190e98a324856c92b7226e357d585 Mon Sep 17 00:00:00 2001 From: RoadToSix <92928205+roadtosixx@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:33:52 +0100 Subject: [PATCH 1/3] fix(cron): validate arguments in RunAt and improve timestamp handling --- [core]/cron/server/main.lua | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/[core]/cron/server/main.lua b/[core]/cron/server/main.lua index bc8f81d00..d9eecee79 100644 --- a/[core]/cron/server/main.lua +++ b/[core]/cron/server/main.lua @@ -1,7 +1,15 @@ local Jobs = {} local LastTime = nil +---@param h number Hour (0-23) +---@param m number Minute (0-59) +---@param cb function Callback to execute function RunAt(h, m, cb) + if type(h) ~= "number" or type(m) ~= "number" or type(cb) ~= "function" then + print("[cron] Invalid arguments to RunAt. Expected (number, number, function).") + return + end + Jobs[#Jobs + 1] = { h = h, m = m, @@ -9,19 +17,25 @@ function RunAt(h, m, cb) } end +---@return number Current timestamp function GetUnixTimestamp() return os.time() end +---@param time number The current Unix timestamp function OnTime(time) + local currentDay = os.date("*t", time).day + local currentMonth = os.date("*t", time).month + local currentYear = os.date("*t", time).year + for i = 1, #Jobs, 1 do local scheduledTimestamp = os.time({ hour = Jobs[i].h, min = Jobs[i].m, sec = 0, -- Assuming tasks run at the start of the minute - day = os.date("%d", time), - month = os.date("%m", time), - year = os.date("%Y", time), + year = currentYear, + month = currentMonth, + day = currentDay }) if time >= scheduledTimestamp and (not LastTime or LastTime < scheduledTimestamp) then @@ -32,20 +46,19 @@ function OnTime(time) end function Tick() - local time = GetUnixTimestamp() + local currentTime = GetUnixTimestamp() - if not LastTime or os.date("%M", time) ~= os.date("%M", LastTime) then - OnTime(time) - LastTime = time + if not LastTime or os.date("%M", currentTime) ~= os.date("%M", LastTime) then + OnTime(currentTime) + LastTime = currentTime end SetTimeout(60000, Tick) end LastTime = GetUnixTimestamp() - Tick() AddEventHandler("cron:runAt", function(h, m, cb) RunAt(h, m, cb) -end) +end) \ No newline at end of file From b28d553b814ba48e96635b8e02ba0278a0d5cfff Mon Sep 17 00:00:00 2001 From: RoadToSix <92928205+roadtosixx@users.noreply.github.com> Date: Sat, 23 Nov 2024 18:39:25 +0100 Subject: [PATCH 2/3] fix(cron): validate arguments in RunAt and improve timestamp handling --- [core]/cron/server/main.lua | 74 +++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/[core]/cron/server/main.lua b/[core]/cron/server/main.lua index d9eecee79..fb2169bb3 100644 --- a/[core]/cron/server/main.lua +++ b/[core]/cron/server/main.lua @@ -1,64 +1,84 @@ -local Jobs = {} -local LastTime = nil +---@class CronJob +---@field h number +---@field m number +---@field cb function|table ----@param h number Hour (0-23) ----@param m number Minute (0-59) ----@param cb function Callback to execute +---@type CronJob[] +local cronJobs = {} +---@type number|false +local lastTimestamp = false + +---@param h number +---@param m number +---@param cb function|table function RunAt(h, m, cb) - if type(h) ~= "number" or type(m) ~= "number" or type(cb) ~= "function" then - print("[cron] Invalid arguments to RunAt. Expected (number, number, function).") + if type(h) ~= "number" or type(m) ~= "number" or (type(cb) ~= "function" and type(cb) ~= "table") then + print("[cron] Invalid arguments to RunAt. Expected (number, number, function/table).") return end - Jobs[#Jobs + 1] = { + cronJobs[#cronJobs + 1] = { h = h, m = m, cb = cb, } end ----@return number Current timestamp +---@return number function GetUnixTimestamp() return os.time() end ----@param time number The current Unix timestamp -function OnTime(time) - local currentDay = os.date("*t", time).day - local currentMonth = os.date("*t", time).month - local currentYear = os.date("*t", time).year +---@param timestamp number +function OnTime(timestamp) + local currentDay = os.date("*t", timestamp).day + local currentMonth = os.date("*t", timestamp).month + local currentYear = os.date("*t", timestamp).year - for i = 1, #Jobs, 1 do + for i = 1, #cronJobs, 1 do local scheduledTimestamp = os.time({ - hour = Jobs[i].h, - min = Jobs[i].m, + hour = cronJobs[i].h, + min = cronJobs[i].m, sec = 0, -- Assuming tasks run at the start of the minute - year = currentYear, + day = currentDay, month = currentMonth, - day = currentDay + year = currentYear, }) - if time >= scheduledTimestamp and (not LastTime or LastTime < scheduledTimestamp) then + if timestamp >= scheduledTimestamp and (not lastTimestamp or lastTimestamp < scheduledTimestamp) then local d = os.date('*t', scheduledTimestamp).wday - Jobs[i].cb(d, Jobs[i].h, Jobs[i].m) + cronJobs[i].cb(d, cronJobs[i].h, cronJobs[i].m) end end end +---@return nil function Tick() - local currentTime = GetUnixTimestamp() + local timestamp = GetUnixTimestamp() - if not LastTime or os.date("%M", currentTime) ~= os.date("%M", LastTime) then - OnTime(currentTime) - LastTime = currentTime + if not lastTimestamp or os.date("%M", timestamp) ~= os.date("%M", lastTimestamp) then + OnTime(timestamp) + lastTimestamp = timestamp end SetTimeout(60000, Tick) end -LastTime = GetUnixTimestamp() +lastTimestamp = GetUnixTimestamp() Tick() +---@param h number +---@param m number +---@param cb function|table AddEventHandler("cron:runAt", function(h, m, cb) + local invokingResource = GetInvokingResource() or "Unknown" + local typeH = type(h) + local typeM = type(m) + local typeCb = type(cb) + + assert(typeH == "number", ("Expected number for h, got %s. Invoking Resource: '%s'"):format(typeH, invokingResource)) + assert(typeM == "number", ("Expected number for m, got %s. Invoking Resource: '%s'"):format(typeM, invokingResource)) + assert(typeCb == "function" or (typeCb == "table" and type(getmetatable(cb)?.__call) == "function"), ("Expected function for cb, got %s. Invoking Resource: '%s'"):format(typeCb, invokingResource)) + RunAt(h, m, cb) -end) \ No newline at end of file +end) From d97dbc8762b6ada7f07385596caf488b1024a5b7 Mon Sep 17 00:00:00 2001 From: Ilias Rbayti <63159154+Kenshiin13@users.noreply.github.com> Date: Sun, 24 Nov 2024 13:53:24 +0100 Subject: [PATCH 3/3] fix typo during merge --- [core]/cron/server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/[core]/cron/server/main.lua b/[core]/cron/server/main.lua index eee892323..0c67dbefa 100644 --- a/[core]/cron/server/main.lua +++ b/[core]/cron/server/main.lua @@ -42,7 +42,7 @@ function OnTime(timestamp) sec = 0, -- Assuming tasks run at the start of the minute day = currentDay, month = currentMonth, - year = currentYear,v + year = currentYear }) if timestamp >= scheduledTimestamp and (not lastTimestamp or lastTimestamp < scheduledTimestamp) then