task scheduler #296
Aliases: task scheduler, scheduler
7 verbs · 19 properties · 3 children
Verbs
| Verb | Spec | Flags | Definer | Lines |
|---|---|---|---|---|
_log | this none this | rxd | #296 | 16 |
_handle_error | this none this | rxd | #296 | 19 |
_do | this none this | rxd | #296 | 32 |
_run | this none this | rxd | #296 | 50 |
_start | this none this | rxd | #296 | 8 |
recycle | this none this | rxd | #296 | 6 |
_readlog | this none this | rxd | #296 | 8 |
Properties
| Property | Definer | Flags | Owner | Value |
|---|---|---|---|---|
help_msg | #296 | rc | #361 | list of 19{"The task scheduler lets you set up things to run at specific frequencies.", "", "Don't mess with $scheduler itself, check out its children:", " - $daily (#404806) (.frequency == 86400)", " - $weekly (#428597) (.frequency == 604800)", " - $gamedaily (#59272) (.frequency = 10800)", " - half-hourly (#441325)", "", "Add a verb to any child of scheduler and it will be guaranteed to run once every .frequency (in seconds). (Just make sure your verb doesn't start with an underscore.) Each of the above objects is +w, which means anyone can put a verb on them. It will run with your permissions etc.", "", "WHAT WILL HAPPEN:", " - your verb will run next check, after it's added. (see .check_frequency, generally .frequency/24)", " - if it's successful and returns a list or string, it will be mailed to you", " - if it fails, a stack trace will be mailed to you, and you will feel bad", " - mail will include total execution time (in real seconds)", "", "ALSO:", " - :_readlog() will spam you with the recent activity on it. e.g., ;$daily:_readlog().", " - @addfeature #202600 (tasknet) to see the scheduler's logs live."} |
frequency | #296 | rc | #361 | 0 |
check_frequency | #296 | rc | #361 | 3600 |
last_runs | #296 | rc | #361 | list of 17{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
log | #296 | rc | #361 | {} |
max_log_lines | #296 | rc | #361 | 250 |
wait_between_tasks | #296 | rc | #361 | 30 |
run_task | #296 | rc | #361 | 0 |
log_to_net | #296 | rc | #361 | #365 |
aliases | #1 | rc | #361 | {"task scheduler", "scheduler"} |
description | #1 | rc | #361 | <clear> |
object_size | #1 | r | #29 | {7737, 1298434650} |
hidden_verbs | #1 | rc | #361 | <clear> |
phelp_msg | #1 | rc | #361 | <clear> |
weight | #1 | rc | #361 | <clear> |
owner_verbs | #1 | rc | #361 | <clear> |
plural_name | #1 | rc | #361 | <clear> |
client_image | #1 | rc | #361 | <clear> |
listening | #1 | rc | #361 | <clear> |
Ancestry
Ancestors (nearest first): #1 root
Children: #297 daily, #298 weekly, #304 gamedaily
Call graph
Source
_log
Referenced by
- #296:_handle_error line 8:
this:_log - #296:_do line 27:
this:_log - #296:_run line 31:
this:_log - #296:_run line 37:
this:_log
Source
1"_log(...) => Write args to this.log"; 2if (caller != this) 3raise(E_PERM); 4endif 5text = tostr(@args); 6log = {@this.log, {time(), text}}; 7if (is_a(this.log_to_net, $net)) 8fork (0) 9this.log_to_net:sys_announce(this.name, ": ", text); 10endfork 11endif 12if (length(log) > this.max_log_lines) 13this.log = log[1..this.max_log_lines]; 14else 15this.log = log; 16endif
_handle_error
Referenced by
- #296:_do line 30:
this:_handle_error
Source
1"_handle_error(STR verbname, THROWN e, INT elapsed_execution_secs, INT time_of_execution) => handle/log a broken task."; 2if (caller != this) 3raise(E_PERM); 4endif 5{v, e, elapsed, when} = args; 6{errcode, errmsg, value, stack} = e; 7elapsed_str = $time_utils:english_time(elapsed); 8this:_log("Got error ", toliteral(errcode), " from :", v, " after ", elapsed_str); 9{verbthis, verbname, verbprog, verbloc} = stack[1][1..4]; 10"remove _do from stack"; 11stack = stack[1..$ - 1]; 12topline = tostr("'", errmsg, "' (", errcode, ") [value = ", value, "]"); 13output = {topline, @$lu:map_arg($ansi, "strip", $rpg:render_error(errmsg, stack))}; 14subj = tostr("ERR: Scheduled task on ", verbloc, " (:", verbname, ")"); 15output = {@output, "", tostr("After ", elapsed_str, " of execution at ", ctime(when))}; 16if (verbprog == #2) 17verbprog = #158; 18endif 19$mail_agent:send_message(this, verbprog, subj, output);
_do
Referenced by
- #296:_run line 42:
this:_do
Source
1"_do(verbname) => run task now."; 2if (caller != this) 3raise(E_PERM); 4endif 5{v} = args; 6fork (0) 7try 8start_time = time(); 9ret = this:(v)(); 10elapsed = time() - start_time; 11elapsed_str = $time_utils:english_time(elapsed); 12if ((typeof(ret) == STR) || (typeof(ret) == LIST)) 13prog = verb_info(this, v)[1]; 14if (prog == #2) 15prog = #158; 16endif 17subj = tostr("OK: Scheduled task on ", this, " (:", v, ")"); 18if (typeof(ret) == LIST) 19text = $su:from_value(ret, 1, 10); 20else 21text = {ret}; 22endif 23text = {"Returned: ", @text, ""}; 24text = {@text, tostr("After ", elapsed_str, " of execution.")}; 25$mail_agent:send_message(this, prog, subj, text); 26endif 27this:_log("Completed :", v, " in ", elapsed_str, " => ", $su:from_value(ret)); 28except e (ANY) 29elapsed = time() - start_time; 30this:_handle_error(v, e, elapsed, start_time); 31endtry 32endfork
_run
Referenced by
none
Source
1"_run() => Check for tasks, repeat infinitely."; 2if (this.frequency < 60) 3player:tell(".frequency for ", $su:nn(this), " is invalid. Must be at LEAST 60 seconds."); 4return; 5endif 6if ((this.check_frequency < 15) || (this.check_frequency > (this.frequency / 2))) 7player:tell(".check_frequency for ", $su:nn(this), " is invalid. Must be >15 seconds, but no more than half of .frequency."); 8return; 9endif 10if (task_valid(this.run_task)) 11if (valid(player)) 12player:tell("A :_run task is already running for ", $su:nn(this), ". [Task ", this.run_task, "]"); 13else 14"This is being run by the server (generally at start.)"; 15endif 16return; 17endif 18if (!caller_perms().wizard) 19player:tell("You can't start this up, you have to be a wizard."); 20return; 21endif 22this.run_task = task_id(); 23while (1) 24for v in (verbs(this)) 25if (v[1] == "_") 26continue; 27endif 28do = 0; 29last_time = `this.last_runs[v] ! E_RANGE'; 30if (last_time == E_RANGE) 31this:_log("Running :", v, " for the first time."); 32do = 1; 33else 34now = time(); 35if ((last_time + this.frequency) < (now + this.check_frequency)) 36since_last_str = $time_utils:english_time(now - last_time); 37this:_log("Running :", v, " -- last run ", since_last_str, " ago"); 38do = 1; 39endif 40endif 41if (do) 42this:_do(v); 43this.last_runs[v] = time(); 44suspend(this.wait_between_tasks); 45else 46yield; 47endif 48endfor 49suspend(this.check_frequency); 50endwhile
_start
Referenced by
none
Source
1if (caller != #0) 2raise(E_PERM); 3endif 4for c in ($ou:leaves_suspended($scheduler)) 5fork (0) 6c:_run(); 7endfork 8endfor
recycle
Referenced by
none
Source
1if (caller.wizard || (caller == this.owner)) 2task_valid(this.run_task) && kill_task(this.run_task); 3return pass(@args); 4else 5return E_PERM; 6endif
_readlog
Referenced by
none
Source
1player:tell("-- Log for ", $su:nn(this), " --"); 2for l in (this.log) 3{when, text} = l; 4when = $time_utils:abbrev_ctime(when); 5player:tell("[", when, "] ", text); 6yield; 7endfor 8player:tell("-- End of log --");