plugins/mod_cron.lua
author Kim Alvefur <zash@zash.se>
Fri, 27 May 2022 14:45:35 +0200
branch0.12
changeset 12530 252ed01896dd
parent 12493 8b42575738f0
child 12981 74b9e05af71e
permissions -rw-r--r--
mod_smacks: Bounce unhandled stanzas from local origin (fix #1759) Sending stanzas with a remote session as origin when the stanzas have a local JID in the from attribute trips validation in core.stanza_router, leading to warnings: > Received a stanza claiming to be from remote.example, over a stream authed for localhost.example Using module:send() uses the local host as origin, which is fine here.
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);