Commit | Line | Data |
8cefc921 |
1 | NAME |
2 | Catalyst::Plugin::Scheduler - Schedule events to run in a cron-like |
3 | fashion |
4 | |
5 | SYNOPSIS |
6 | use Catalyst qw/Scheduler/; |
7 | |
8 | # run remove_sessions in the Cron controller every hour |
9 | __PACKAGE__->schedule( |
10 | at => '0 * * * *', |
11 | event => '/cron/remove_sessions' |
12 | ); |
13 | |
14 | # Run a subroutine at 4:05am every Sunday |
15 | __PACKAGE__->schedule( |
16 | at => '5 4 * * sun', |
17 | event => \&do_stuff, |
18 | ); |
19 | |
20 | # A long-running scheduled event that must be triggered |
21 | # manually by an authorized user |
22 | __PACKAGE__->schedule( |
23 | trigger => 'rebuild_search_index', |
24 | event => '/cron/rebuild_search_index', |
25 | ); |
26 | $ wget -q http://www.myapp.com/?schedule_trigger=rebuild_search_index |
27 | |
28 | DESCRIPTION |
29 | This plugin allows you to schedule events to run at recurring intervals. |
30 | Events will run during the first request which meets or exceeds the |
31 | specified time. Depending on the level of traffic to the application, |
32 | events may or may not run at exactly the correct time, but it should be |
33 | enough to satisfy many basic scheduling needs. |
34 | |
35 | CONFIGURATION |
36 | Configuration is optional and is specified in |
37 | MyApp->config->{scheduler}. |
38 | |
39 | logging |
40 | Set to 1 to enable logging of events as they are executed. This option |
41 | is enabled by default when running under -Debug mode. Errors are always |
42 | logged regardless of the value of this option. |
43 | |
44 | time_zone |
45 | The time zone of your system. This will be autodetected where possible, |
46 | or will default to UTC (GMT). You can override the detection by |
47 | providing a valid DateTime time zone string, such as 'America/New_York'. |
48 | |
49 | state_file |
50 | The current state of every event is stored in a file. By default this is |
51 | $APP_HOME/scheduler.state. This file is created on the first request if |
52 | it does not already exist. |
53 | |
54 | yaml_file |
55 | The location of the optional YAML event configuration file. By default |
56 | this is $APP_HOME/scheduler.yml. |
57 | |
58 | hosts_allow |
59 | This option specifies IP addresses for trusted users. This option |
60 | defaults to 127.0.0.1. Multiple addresses can be specified by using an |
61 | array reference. This option is used for both events where auto_run is |
62 | set to 0 and for manually-triggered events. |
63 | |
64 | __PACKAGE__->config->{scheduler}->{hosts_allow} = '192.168.1.1'; |
65 | __PACKAGE__->config->{scheduler}->{hosts_allow} = [ |
66 | '127.0.0.1', |
67 | '192.168.1.1' |
68 | ]; |
69 | |
70 | SCHEDULING |
71 | AUTOMATED EVENTS |
72 | Events are scheduled by calling the class method "schedule". |
73 | |
74 | MyApp->schedule( |
75 | at => '0 * * * *', |
76 | event => '/cron/remove_sessions', |
77 | ); |
78 | |
79 | package MyApp::Controller::Cron; |
80 | |
81 | sub remove_sessions : Private { |
82 | my ( $self, $c ) = @_; |
83 | |
84 | $c->delete_expired_sessions; |
85 | } |
86 | |
87 | at |
88 | The time to run an event is specified using crontab(5)-style syntax. |
89 | |
90 | 5 0 * * * # 5 minutes after midnight, every day |
91 | 15 14 1 * * # run at 2:15pm on the first of every month |
92 | 0 22 * * 1-5 # run at 10 pm on weekdays |
93 | 5 4 * * sun # run at 4:05am every Sunday |
94 | |
95 | From crontab(5): |
96 | |
97 | field allowed values |
98 | ----- -------------- |
99 | minute 0-59 |
100 | hour 0-23 |
101 | day of month 1-31 |
102 | month 0-12 (or names, see below) |
103 | day of week 0-7 (0 or 7 is Sun, or use names) |
104 | |
105 | Instead of the first five fields, one of seven special strings may |
106 | appear: |
107 | |
108 | string meaning |
109 | ------ ------- |
110 | @yearly Run once a year, "0 0 1 1 *". |
111 | @annually (same as @yearly) |
112 | @monthly Run once a month, "0 0 1 * *". |
113 | @weekly Run once a week, "0 0 * * 0". |
114 | @daily Run once a day, "0 0 * * *". |
115 | @midnight (same as @daily) |
116 | @hourly Run once an hour, "0 * * * *". |
117 | |
118 | event |
119 | The event to run at the specified time can be either a Catalyst private |
120 | action path or a coderef. Both types of event methods will receive the |
121 | $c object from the current request, but you must not rely on any |
122 | request-specific information present in $c as it will be from a random |
123 | user request at or near the event's specified run time. |
124 | |
125 | Important: Methods used for events should be marked "Private" so that |
126 | they can not be executed via the browser. |
127 | |
128 | auto_run |
129 | The auto_run parameter specifies when the event is allowed to be |
130 | executed. By default this option is set to 1, so the event will be |
131 | executed during the first request that matches the specified time in |
132 | "at". |
133 | |
134 | If set to 0, the event will only run when a request is made by a user |
135 | from an authorized address. The purpose of this option is to allow |
136 | long-running tasks to execute only for certain users. |
137 | |
138 | MyApp->schedule( |
139 | at => '0 0 * * *', |
140 | event => '/cron/rebuild_search_index', |
141 | auto_run => 0, |
142 | ); |
143 | |
144 | package MyApp::Controller::Cron; |
145 | |
146 | sub rebuild_search_index : Private { |
147 | my ( $self, $c ) = @_; |
148 | |
149 | # rebuild the search index, this may take a long time |
150 | } |
151 | |
152 | Now, the search index will only be rebuilt when a request is made from a |
153 | user whose IP address matches the list in the "hosts_allow" config |
154 | option. To run this event, you probably want to ping the app from a cron |
155 | job. |
156 | |
157 | 0 0 * * * wget -q http://www.myapp.com/ |
158 | |
159 | MANUAL EVENTS |
160 | To create an event that does not run on a set schedule and must be |
161 | manually triggered, you can specify the "trigger" option instead of |
162 | "at". |
163 | |
164 | __PACKAGE__->schedule( |
165 | trigger => 'send_email', |
166 | event => '/events/send_email', |
167 | ); |
168 | |
169 | The event may then be triggered by a standard web request from an |
170 | authorized user. The trigger to run is specified by using a special GET |
171 | parameter, 'schedule_trigger'; the path requested does not matter. |
172 | |
173 | http://www.myapp.com/?schedule_trigger=send_email |
174 | |
175 | By default, manual events may only be triggered by requests made from |
176 | localhost (127.0.0.1). To allow other addresses to run events, use the |
177 | configuration option "hosts_allow". |
178 | |
179 | SCHEDULING USING A YAML FILE |
180 | As an alternative to using the schedule() method, you may define |
181 | scheduled events in an external YAML file. By default, the plugin looks |
182 | for the existence of a file called "schedule.yml" in your application's |
183 | home directory. You can change the filename using the configuration |
184 | option "yaml_file". |
185 | |
186 | Modifications to this file will be re-read once per minute during the |
187 | normal event checking process. |
188 | |
189 | Here's an example YAML configuration file with 4 events. Each event is |
190 | denoted with a '-' character, followed by the same parameters used by |
191 | the "schedule" method. Note that coderef events are not supported by the |
192 | YAML file. |
193 | |
194 | --- |
195 | - at: '* * * * *' |
196 | event: /cron/delete_sessions |
197 | - event: /cron/send_email |
198 | trigger: send_email |
199 | - at: '@hourly' |
200 | event: /cron/hourly |
201 | - at: 0 0 * * * |
202 | auto_run: 0 |
203 | event: /cron/rebuild_search_index |
204 | |
205 | SECURITY |
206 | All events are run inside of an eval container. This protects the user |
207 | from receiving any error messages or page crashes if an event fails to |
208 | run properly. All event errors are logged, even if logging is disabled. |
209 | |
210 | PLUGIN SUPPORT |
211 | Other plugins may register scheduled events if they need to perform |
212 | periodic maintenance. Plugin authors, be sure to inform your users if |
213 | you do this! Events should be registered from a plugin's "setup" method. |
214 | |
215 | sub setup { |
216 | my $c = shift; |
217 | $c->NEXT::setup(@_); |
218 | |
219 | if ( $c->can('schedule') ) { |
220 | $c->schedule( |
221 | at => '0 * * * *', |
222 | event => \&cleanup, |
223 | ); |
224 | } |
225 | } |
226 | |
227 | CAVEATS |
228 | The time at which an event will run is determined completely by the |
229 | requests made to the application. Apps with heavy traffic may have |
230 | events run at very close to the correct time, whereas apps with low |
231 | levels of traffic may see events running much later than scheduled. If |
232 | this is a problem, you can use a real cron entry that simply hits your |
233 | application at the desired time. |
234 | |
235 | 0 * * * * wget -q http://www.myapp.com/ |
236 | |
237 | Events which consume a lot of time will slow the request processing for |
238 | the user who triggers the event. For these types of events, you should |
239 | use auto_run => 0 or manual event triggering. |
240 | |
241 | PERFORMANCE |
242 | The plugin only checks once per minute if any events need to be run, so |
243 | the overhead on each request is minimal. On my test server, the |
244 | difference between running with Scheduler and without was only around |
245 | 0.02% (0.004 seconds). |
246 | |
247 | Of course, when a scheduled event runs, performance will depend on |
248 | what's being run in the event. |
249 | |
250 | METHODS |
251 | schedule |
252 | Schedule is a class method for adding scheduled events. See the |
253 | "SCHEDULING"" in " section for more information. |
254 | |
255 | scheduler_state |
256 | The current state of all scheduled events is available in an easy-to-use |
257 | format by calling $c->scheduler_state. You can use this data to build an |
258 | admin view into the scheduling engine, for example. This same data is |
259 | also displayed on the Catalyst debug screen. |
260 | |
261 | This method returns an array reference containing a hash reference for |
262 | each event. |
263 | |
264 | [ |
265 | { |
266 | 'last_run' => '2005-12-29 16:29:33 EST', |
267 | 'auto_run' => 1, |
268 | 'last_output' => 1, |
269 | 'at' => '0 0 * * *', |
270 | 'next_run' => '2005-12-30 00:00:00 EST', |
271 | 'event' => '/cron/session_cleanup' |
272 | }, |
273 | { |
274 | 'auto_run' => 1, |
275 | 'at' => '0 0 * * *', |
276 | 'next_run' => '2005-12-30 00:00:00 EST', |
277 | 'event' => '/cron/build_rss' |
278 | }, |
279 | ] |
280 | |
281 | INTERNAL METHODS |
282 | The following methods are extended by this plugin. |
283 | |
284 | dispatch |
285 | The main scheduling logic takes place during the dispatch phase. |
286 | |
287 | dump_these |
288 | On the Catalyst debug screen, all scheduled events are displayed |
289 | along with the next time they will be executed. |
290 | |
291 | setup |
292 | |
293 | SEE ALSO |
294 | crontab(5) |
295 | |
296 | AUTHOR |
297 | Andy Grundman, <andy@hybridized.org> |
298 | |
299 | COPYRIGHT |
300 | This program is free software, you can redistribute it and/or modify it |
301 | under the same terms as Perl itself. |
302 | |