|
1 module:set_global(); |
|
2 |
|
3 local async = require("util.async"); |
|
4 |
|
5 local periods = { hourly = 3600; daily = 86400 } |
|
6 |
|
7 local active_hosts = {} |
|
8 |
|
9 function module.add_host(host_module) |
|
10 |
|
11 local last_run_times = host_module:open_store("cron", "map"); |
|
12 active_hosts[host_module.host] = true; |
|
13 |
|
14 local function save_task(task, started_at) last_run_times:set(nil, task.id, started_at); end |
|
15 |
|
16 local function task_added(event) |
|
17 local task = event.item; |
|
18 if task.name == nil then task.name = task.when; end |
|
19 if task.id == nil then task.id = event.source.name .. "/" .. task.name:gsub("%W", "_"):lower(); end |
|
20 if task.last == nil then task.last = last_run_times:get(nil, task.id); end |
|
21 task.save = save_task; |
|
22 module:log("debug", "%s task %s added, last run %s", task.when, task.id, |
|
23 task.last and require("util.datetime").datetime(task.last) or "never"); |
|
24 return true |
|
25 end |
|
26 |
|
27 local function task_removed(event) |
|
28 local task = event.item; |
|
29 host_module:log("debug", "Task %s removed", task.id); |
|
30 return true |
|
31 end |
|
32 |
|
33 host_module:handle_items("task", task_added, task_removed, true); |
|
34 |
|
35 function host_module.unload() active_hosts[host_module.host] = nil; end |
|
36 end |
|
37 |
|
38 local function should_run(when, last) return not last or last + periods[when] <= os.time() end |
|
39 |
|
40 local function run_task(task) |
|
41 local started_at = os.time(); |
|
42 task:run(started_at); |
|
43 task:save(started_at); |
|
44 end |
|
45 |
|
46 local task_runner = async.runner(run_task); |
|
47 module:add_timer(1, function() |
|
48 module:log("info", "Running periodic tasks"); |
|
49 local delay = 3600; |
|
50 for host in pairs(active_hosts) do |
|
51 module:log("debug", "Running periodic tasks for host %s", host); |
|
52 for _, task in ipairs(module:context(host):get_host_items("task")) do |
|
53 module:log("debug", "Considering %s task %s (%s)", task.when, task.id, task.run); |
|
54 if should_run(task.when, task.last) then task_runner:run(task); end |
|
55 end |
|
56 end |
|
57 module:log("debug", "Wait %ds", delay); |
|
58 return delay |
|
59 end); |