plugins/mod_cron.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 11 Oct 2022 11:37:55 +0100
changeset 12767 d26eefe98d09
parent 12493 8b42575738f0
child 12981 74b9e05af71e
permissions -rw-r--r--
util.dbuffer: Add efficient shortcuts for discard() in certain cases If the buffer is already empty, nothing to do. If we're throwing away the whole buffer, we can just empty it and avoid read_chunk() (which in turn may collapse()). These shortcuts are much more efficient.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
module:set_global();
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local async = require("util.async");
12004
00c57684cf20 mod_cron: Follow convention of imports at the top
Kim Alvefur <zash@zash.se>
parents: 11999
diff changeset
     4
local datetime = require("util.datetime");
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
12006
cbed7d8d8f35 mod_cron: Add a 'weekly' job frequency
Kim Alvefur <zash@zash.se>
parents: 12005
diff changeset
     6
local periods = { hourly = 3600; daily = 86400; weekly = 7 * 86400 }
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
local active_hosts = {}
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
function module.add_host(host_module)
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
	local last_run_times = host_module:open_store("cron", "map");
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
	active_hosts[host_module.host] = true;
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
	local function save_task(task, started_at) last_run_times:set(nil, task.id, started_at); end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
	local function task_added(event)
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
		local task = event.item;
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
		if task.name == nil then task.name = task.when; end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
		if task.id == nil then task.id = event.source.name .. "/" .. task.name:gsub("%W", "_"):lower(); end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
		if task.last == nil then task.last = last_run_times:get(nil, task.id); end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
		task.save = save_task;
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
		module:log("debug", "%s task %s added, last run %s", task.when, task.id,
12004
00c57684cf20 mod_cron: Follow convention of imports at the top
Kim Alvefur <zash@zash.se>
parents: 11999
diff changeset
    24
			task.last and datetime.datetime(task.last) or "never");
12005
5a8c6f9a4583 mod_cron: Initialize timestamp of new tasks to start of period
Kim Alvefur <zash@zash.se>
parents: 12004
diff changeset
    25
		if task.last == nil then
11999
bbd3ac65640d mod_cron: Initialize daily tasks so they run around midnight UTC
Kim Alvefur <zash@zash.se>
parents: 11990
diff changeset
    26
			local now = os.time();
12005
5a8c6f9a4583 mod_cron: Initialize timestamp of new tasks to start of period
Kim Alvefur <zash@zash.se>
parents: 12004
diff changeset
    27
			task.last = now - now % periods[task.when];
11999
bbd3ac65640d mod_cron: Initialize daily tasks so they run around midnight UTC
Kim Alvefur <zash@zash.se>
parents: 11990
diff changeset
    28
		end
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
		return true
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
	end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
	local function task_removed(event)
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
		local task = event.item;
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
		host_module:log("debug", "Task %s removed", task.id);
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
		return true
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
	end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
	host_module:handle_items("task", task_added, task_removed, true);
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
	function host_module.unload() active_hosts[host_module.host] = nil; end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
12190
7f25ac9d8f0d mod_cron: Allow for a small amount of timer drift
Kim Alvefur <zash@zash.se>
parents: 12013
diff changeset
    43
local function should_run(when, last) return not last or last + periods[when] * 0.995 <= os.time() end
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
local function run_task(task)
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
	local started_at = os.time();
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	task:run(started_at);
12493
8b42575738f0 mod_cron: Fix recording last task run time #1751
Kim Alvefur <zash@zash.se>
parents: 12190
diff changeset
    48
	task.last = started_at;
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
	task:save(started_at);
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
local task_runner = async.runner(run_task);
12013
f6fff0658108 mod_cron: Expose the One Timer via module environment
Kim Alvefur <zash@zash.se>
parents: 12006
diff changeset
    53
scheduled = module:add_timer(1, function()
11990
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
	module:log("info", "Running periodic tasks");
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
	local delay = 3600;
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
	for host in pairs(active_hosts) do
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
		module:log("debug", "Running periodic tasks for host %s", host);
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
		for _, task in ipairs(module:context(host):get_host_items("task")) do
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
			module:log("debug", "Considering %s task %s (%s)", task.when, task.id, task.run);
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
			if should_run(task.when, task.last) then task_runner:run(task); end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
		end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	end
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
	module:log("debug", "Wait %ds", delay);
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
	return delay
3d5135e8a2a7 mod_cron: Initial commit of periodic task runner
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
end);