| 1 |
ELYSIA_CRON
|
| 2 |
by Eric Berdondini (gotheric)
|
| 3 |
<eric@void.it>
|
| 4 |
|
| 5 |
Features:
|
| 6 |
- crontab-like scheduling configuration of each job.
|
| 7 |
- grouping of jobs in channels (parallel lines of execution).
|
| 8 |
- you can disable all jobs, an entire channel or a single job via configuration.
|
| 9 |
- force execution of a single cron job on demand
|
| 10 |
- change the priority/order of job execution
|
| 11 |
- time statistics of each job and of the whole channel.
|
| 12 |
- modules can define extra cron tasks, each one with own default cron-rules
|
| 13 |
(site administrators can override them by configuration).
|
| 14 |
- administrators can define custom jobs (call to functions with parameters)
|
| 15 |
- protection from external cron calling by cron_key or allowed host list.
|
| 16 |
- ensure all shutdown hook functions launched by cron jobs are launched inside
|
| 17 |
cron protection (ex: search_cron() will launch search_update_totals() in a
|
| 18 |
shutdown hook).
|
| 19 |
|
| 20 |
For installation instructions read INSTALL.TXT
|
| 21 |
|
| 22 |
-----------------------------------------------------------------------------
|
| 23 |
CHANNELS
|
| 24 |
-----------------------------------------------------------------------------
|
| 25 |
|
| 26 |
Channels are groups of tasks. Each channel is a "parallel line" of execution
|
| 27 |
(= multiple channels can be executed simultaneously).
|
| 28 |
Tasks inside a channel will be executed sequentially (if they should).
|
| 29 |
|
| 30 |
WARNING: It's not recommended to create more than 2 or 3 channels.
|
| 31 |
Every channel will increase the delay between each cron check (of the same
|
| 32 |
channel), because each cron call will cycle between all channels.
|
| 33 |
So, for example:
|
| 34 |
If you have 1 channel it will be checked once a minute.
|
| 35 |
If you have 2 channel each one will be checked every 2 minutes (almost usually,
|
| 36 |
when the other one is running it will be checked once a minute).
|
| 37 |
It you have 10 channels there will be a check every 10 minutes... if you have
|
| 38 |
a job that should be executed every 5 minutes it won't do so!
|
| 39 |
|
| 40 |
-----------------------------------------------------------------------------
|
| 41 |
RULES AND SCRIPT SYNTAX
|
| 42 |
-----------------------------------------------------------------------------
|
| 43 |
|
| 44 |
1. FIELDS ORDER
|
| 45 |
---------------------------------
|
| 46 |
|
| 47 |
+---------------- minute (0 - 59)
|
| 48 |
| +------------- hour (0 - 23)
|
| 49 |
| | +---------- day of month (1 - 31)
|
| 50 |
| | | +------- month (1 - 12)
|
| 51 |
| | | | +---- day of week (0 - 7) (Sunday=0)
|
| 52 |
| | | | |
|
| 53 |
* * * * *
|
| 54 |
|
| 55 |
Each of the patterns from the first five fields may be either * (an asterisk),
|
| 56 |
which matches all legal values, or a list of elements separated by commas
|
| 57 |
(see below).
|
| 58 |
|
| 59 |
For "day of the week" (field 5), 0 is considered Sunday, 6 is Saturday (7 is
|
| 60 |
an illegal value)
|
| 61 |
|
| 62 |
A job is executed when the time/date specification fields all match the current
|
| 63 |
time and date. There is one exception: if both "day of month" and "day of week"
|
| 64 |
are restricted (not "*"), then either the "day of month" field (3) or the "day
|
| 65 |
of week" field (5) must match the current day (even though the other of the two
|
| 66 |
fields need not match the current day).
|
| 67 |
|
| 68 |
2. FIELDS OPERATOR
|
| 69 |
---------------------------------
|
| 70 |
|
| 71 |
There are several ways of specifying multiple date/time values in a field:
|
| 72 |
|
| 73 |
* The comma (',') operator specifies a list of values, for example: "1,3,4,7,8"
|
| 74 |
* The dash ('-') operator specifies a range of values, for example: "1-6", which
|
| 75 |
is equivalent to "1,2,3,4,5,6"
|
| 76 |
* The asterisk ('*') operator specifies all possible values for a field. For
|
| 77 |
example, an asterisk in the hour time field would be equivalent to 'every hour'
|
| 78 |
(subject to matching other specified fields).
|
| 79 |
* The slash ('/') operator (called "step") can be used to skip a given number of
|
| 80 |
values. For example, "*/3" in the hour time field is equivalent to
|
| 81 |
"0,3,6,9,12,15,18,21".
|
| 82 |
|
| 83 |
3. EXAMPLES
|
| 84 |
---------------------------------
|
| 85 |
|
| 86 |
*/15 * * * : Execute job every 15 minutes
|
| 87 |
0 2,14 * * *: Execute job every day at 2:00 and 14:00
|
| 88 |
0 2 * * 1-5: Execute job at 2:00 of every working day
|
| 89 |
0 12 1 */2 1: Execute job every 2 month, at 12:00 of first day of the month OR at
|
| 90 |
every monday.
|
| 91 |
|
| 92 |
4. SCRIPTS
|
| 93 |
---------------------------------
|
| 94 |
|
| 95 |
You can use the script section to easily create new jobs (by calling a php function)
|
| 96 |
or to change the scheduling of an existing job.
|
| 97 |
|
| 98 |
Every line of the script can be a comment (if it starts with #) or a job definition.
|
| 99 |
|
| 100 |
The syntax of a job definition is:
|
| 101 |
<-> [rule] <ctx:CONTEXT> [job]
|
| 102 |
|
| 103 |
(Tokens betweens [] are mandatory)
|
| 104 |
|
| 105 |
* <->: a line starting with "-" means that the job is DISABLED.
|
| 106 |
* [rule]: a crontab schedule rule. See above.
|
| 107 |
* <ctx:CONTEXT>: set the context of the job.
|
| 108 |
* [job]: could be the name of a supported job (for example: 'search_cron') or a
|
| 109 |
function call, ending with ; (for example: 'process_queue();').
|
| 110 |
|
| 111 |
A comment on the line just preceding a job definition is considered the job
|
| 112 |
description.
|
| 113 |
|
| 114 |
Remember that script OVERRIDES all settings on single jobs sections or context
|
| 115 |
sections of the configuration
|
| 116 |
|
| 117 |
5. EXAMPLES OF SCRIPT
|
| 118 |
---------------------------------
|
| 119 |
|
| 120 |
# Search indexing every 2 hours (i'm setting this as the job description)
|
| 121 |
0 */2 * * * search_cron
|
| 122 |
|
| 123 |
# I'll check for module status only on sunday nights
|
| 124 |
# (and this is will not be the job description, see the empty line below)
|
| 125 |
|
| 126 |
0 2 * * 0 update_status_cron
|
| 127 |
|
| 128 |
# Trackback ping process every 15min and on a channel called "net"
|
| 129 |
*/15 * * * * ctx:net trackback_cron
|
| 130 |
|
| 131 |
# Disable node_cron (i must set the cron rule even if disabled)
|
| 132 |
- */15 * * * * node_cron
|
| 133 |
|
| 134 |
# Launch function send_summary_mail('test@test.com', false); every night
|
| 135 |
# And set its description to "Send daily summary"
|
| 136 |
# Send daily summary
|
| 137 |
0 1 * * * send_summary_mail('test@test.com', false);
|
| 138 |
|
| 139 |
|
| 140 |
-----------------------------------------------------------------------------
|
| 141 |
MODULE API
|
| 142 |
-----------------------------------------------------------------------------
|
| 143 |
|
| 144 |
You can extend cron functionality in you modules by using elysia_cron api.
|
| 145 |
With it you can:
|
| 146 |
- have more than one cron job
|
| 147 |
- have a different schedule rule for each cron job defined
|
| 148 |
- set a description for each cron job
|
| 149 |
|
| 150 |
To use this functionalities module should implement cronapi hook:
|
| 151 |
|
| 152 |
function module_cronapi($op, $job = NULL) {
|
| 153 |
...
|
| 154 |
}
|
| 155 |
|
| 156 |
$op can have 3 values:
|
| 157 |
- 'list': you should return the list of available jobs, in the form
|
| 158 |
array(
|
| 159 |
array( 'job' => 'description' ),
|
| 160 |
array( 'job' => 'description' ),
|
| 161 |
...
|
| 162 |
)
|
| 163 |
'job' could be the name of a real function or an identifier used with
|
| 164 |
$op = 'execute' (see below).
|
| 165 |
Warn: 'job' should be a unique identified, even if it's not a function
|
| 166 |
name.
|
| 167 |
- 'rule' : when called with this method, $job variable will contain the
|
| 168 |
job name you should return the crun rule of.
|
| 169 |
The rule you return is the default/module preferred schedule rule.
|
| 170 |
An administrator can always override it to fit his needs.
|
| 171 |
- 'execute' : when the system needs to call the job task, if no function
|
| 172 |
with the same of the job exists, it will call the cronapi with this
|
| 173 |
value and with $job filled with the name of the task to execute.
|
| 174 |
|
| 175 |
Example:
|
| 176 |
Assume your module needs 2 cron tasks: one executed every hour (process_queue)
|
| 177 |
and one executed once a day (send_summary_mail).
|
| 178 |
You can do this with this cronapi:
|
| 179 |
|
| 180 |
function module_cronapi($op, $job = NULL) {
|
| 181 |
switch ($op) {
|
| 182 |
case 'list':
|
| 183 |
return array(
|
| 184 |
'module_process_queue' => 'Process queue of new data',
|
| 185 |
'module_send_summary_mail' => 'Send summary of data processed'
|
| 186 |
);
|
| 187 |
case 'rule':
|
| 188 |
if ($job == 'module_process_queue') return '0 * * * *';
|
| 189 |
else return '0 1 * * *';
|
| 190 |
case 'execute':
|
| 191 |
if ($job == 'module_process_queue') {
|
| 192 |
... do the job ...
|
| 193 |
}
|
| 194 |
// Just for example, module_send_summary_mail is on a separate
|
| 195 |
// function (see below)
|
| 196 |
}
|
| 197 |
}
|
| 198 |
|
| 199 |
function module_send_summary_mail() {
|
| 200 |
... do the job ...
|
| 201 |
}
|
| 202 |
|
| 203 |
HANDLING DEFAULT MODULE_CRON FUNCTION
|
| 204 |
-------------------------------------
|
| 205 |
|
| 206 |
To support standard drupal cron all cron hooks (*_cron function) are
|
| 207 |
automatically added to supported jobs, even if you don't declare them
|
| 208 |
on cronapi hook (ore you don't implement the hook at all).
|
| 209 |
However you can define job description and job rule in the same way as
|
| 210 |
above (considering the job an external function).
|
| 211 |
|
| 212 |
Example:
|
| 213 |
function module_cronapi($op, $job = NULL) {
|
| 214 |
switch ($op) {
|
| 215 |
case 'list':
|
| 216 |
return array(
|
| 217 |
'module_cron' => 'Standard cron process',
|
| 218 |
);
|
| 219 |
case 'rule':
|
| 220 |
return '*/15 * * * *';
|
| 221 |
}
|
| 222 |
}
|
| 223 |
|
| 224 |
function module_cron() {
|
| 225 |
...
|
| 226 |
// this is the standard cron hook, but with cronapi above
|
| 227 |
// it has a default rule (execution every 15 minutes) and
|
| 228 |
// a description
|
| 229 |
...
|
| 230 |
}
|
| 231 |
|
| 232 |
-----------------------------------------------------------------------------
|
| 233 |
THEMING & JOB DESCRIPTION
|
| 234 |
-----------------------------------------------------------------------------
|
| 235 |
|
| 236 |
If you want to have a nicer cron administration page with all modules
|
| 237 |
description, and assuming only a few modules supports cronapi hooks,
|
| 238 |
you can add your own description by script (see above) or by
|
| 239 |
'elysia_cron_description' theme function.
|
| 240 |
|
| 241 |
For example, in your phptemplate theme, you can declare:
|
| 242 |
|
| 243 |
function phptemplate_elysia_cron_description($job) {
|
| 244 |
switch($job) {
|
| 245 |
case 'job 1': return 'First job';
|
| 246 |
case 'job 2': return 'Second job';
|
| 247 |
default: return theme_elysia_cron_description($job);
|
| 248 |
}
|
| 249 |
}
|
| 250 |
|
| 251 |
Note: module default theme_elysia_cron_description($job) already contains
|
| 252 |
some common tasks descriptions.
|
| 253 |
|
| 254 |
-----------------------------------------------------------------------------
|
| 255 |
CREDITS
|
| 256 |
-----------------------------------------------------------------------------
|
| 257 |
|
| 258 |
Elysia cron is a part of the Elysia project (but could be used stand alone
|
| 259 |
with no limitation).
|
| 260 |
|
| 261 |
Developing is sponsored by :
|
| 262 |
Void Labs s.n.c
|
| 263 |
http://www.void.it
|