[Catalyst-commits] r7376 - in trunk/Catalyst-Plugin-Scheduler: .
lib/Catalyst/Plugin
andyg at dev.catalyst.perl.org
andyg at dev.catalyst.perl.org
Sat Jan 12 15:51:06 GMT 2008
Author: andyg
Date: 2008-01-12 15:51:06 +0000 (Sat, 12 Jan 2008)
New Revision: 7376
Added:
trunk/Catalyst-Plugin-Scheduler/README
Modified:
trunk/Catalyst-Plugin-Scheduler/Build.PL
trunk/Catalyst-Plugin-Scheduler/Changes
trunk/Catalyst-Plugin-Scheduler/MANIFEST
trunk/Catalyst-Plugin-Scheduler/Makefile.PL
trunk/Catalyst-Plugin-Scheduler/lib/Catalyst/Plugin/Scheduler.pm
Log:
Scheduler 0.08, patch from hovenko to remove state file at startup
Modified: trunk/Catalyst-Plugin-Scheduler/Build.PL
===================================================================
--- trunk/Catalyst-Plugin-Scheduler/Build.PL 2008-01-12 15:19:42 UTC (rev 7375)
+++ trunk/Catalyst-Plugin-Scheduler/Build.PL 2008-01-12 15:51:06 UTC (rev 7376)
@@ -13,7 +13,6 @@
'YAML' => 0,
},
create_makefile_pl => 'passthrough',
- create_readme => 1,
test_files => [
glob('t/*.t')
]
Modified: trunk/Catalyst-Plugin-Scheduler/Changes
===================================================================
--- trunk/Catalyst-Plugin-Scheduler/Changes 2008-01-12 15:19:42 UTC (rev 7375)
+++ trunk/Catalyst-Plugin-Scheduler/Changes 2008-01-12 15:51:06 UTC (rev 7376)
@@ -1,5 +1,8 @@
Revision history for Perl extension Catalyst::Plugin::Scheduler
+0.08 2008-01-12 11:00:00
+ - Clear existing state file during startup. (hovenko)
+
0.07 2006-07-17 12:15:00
- Fix for loading the config with YAML 0.60+
- Prefer YAML::Syck, with fallback to YAML.pm
Modified: trunk/Catalyst-Plugin-Scheduler/MANIFEST
===================================================================
--- trunk/Catalyst-Plugin-Scheduler/MANIFEST 2008-01-12 15:19:42 UTC (rev 7375)
+++ trunk/Catalyst-Plugin-Scheduler/MANIFEST 2008-01-12 15:51:06 UTC (rev 7376)
@@ -8,6 +8,8 @@
t/01use.t
t/02pod.t
t/03podcoverage.t
+t/04critic.rc
+t/04critic.t
t/04schedule.t
t/05auto_run.t
t/06trigger.t
Modified: trunk/Catalyst-Plugin-Scheduler/Makefile.PL
===================================================================
--- trunk/Catalyst-Plugin-Scheduler/Makefile.PL 2008-01-12 15:19:42 UTC (rev 7375)
+++ trunk/Catalyst-Plugin-Scheduler/Makefile.PL 2008-01-12 15:51:06 UTC (rev 7376)
@@ -17,15 +17,15 @@
# Save this 'cause CPAN will chdir all over the place.
my $cwd = Cwd::cwd();
- my $makefile = File::Spec->rel2abs($0);
- CPAN::Shell->install('Module::Build::Compat')
- or die " *** Cannot install without Module::Build. Exiting ...\n";
+ CPAN::Shell->install('Module::Build::Compat');
+ CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
+ or die "Couldn't install Module::Build, giving up.\n";
chdir $cwd or die "Cannot chdir() back to $cwd: $!";
}
eval "use Module::Build::Compat 0.02; 1" or die $@;
- use lib '_build/lib';
+
Module::Build::Compat->run_build_pl(args => \@ARGV);
require Module::Build;
Module::Build::Compat->write_makefile(build_class => 'Module::Build');
Added: trunk/Catalyst-Plugin-Scheduler/README
===================================================================
--- trunk/Catalyst-Plugin-Scheduler/README (rev 0)
+++ trunk/Catalyst-Plugin-Scheduler/README 2008-01-12 15:51:06 UTC (rev 7376)
@@ -0,0 +1,302 @@
+NAME
+ Catalyst::Plugin::Scheduler - Schedule events to run in a cron-like
+ fashion
+
+SYNOPSIS
+ use Catalyst qw/Scheduler/;
+
+ # run remove_sessions in the Cron controller every hour
+ __PACKAGE__->schedule(
+ at => '0 * * * *',
+ event => '/cron/remove_sessions'
+ );
+
+ # Run a subroutine at 4:05am every Sunday
+ __PACKAGE__->schedule(
+ at => '5 4 * * sun',
+ event => \&do_stuff,
+ );
+
+ # A long-running scheduled event that must be triggered
+ # manually by an authorized user
+ __PACKAGE__->schedule(
+ trigger => 'rebuild_search_index',
+ event => '/cron/rebuild_search_index',
+ );
+ $ wget -q http://www.myapp.com/?schedule_trigger=rebuild_search_index
+
+DESCRIPTION
+ This plugin allows you to schedule events to run at recurring intervals.
+ Events will run during the first request which meets or exceeds the
+ specified time. Depending on the level of traffic to the application,
+ events may or may not run at exactly the correct time, but it should be
+ enough to satisfy many basic scheduling needs.
+
+CONFIGURATION
+ Configuration is optional and is specified in
+ MyApp->config->{scheduler}.
+
+ logging
+ Set to 1 to enable logging of events as they are executed. This option
+ is enabled by default when running under -Debug mode. Errors are always
+ logged regardless of the value of this option.
+
+ time_zone
+ The time zone of your system. This will be autodetected where possible,
+ or will default to UTC (GMT). You can override the detection by
+ providing a valid DateTime time zone string, such as 'America/New_York'.
+
+ state_file
+ The current state of every event is stored in a file. By default this is
+ $APP_HOME/scheduler.state. This file is created on the first request if
+ it does not already exist.
+
+ yaml_file
+ The location of the optional YAML event configuration file. By default
+ this is $APP_HOME/scheduler.yml.
+
+ hosts_allow
+ This option specifies IP addresses for trusted users. This option
+ defaults to 127.0.0.1. Multiple addresses can be specified by using an
+ array reference. This option is used for both events where auto_run is
+ set to 0 and for manually-triggered events.
+
+ __PACKAGE__->config->{scheduler}->{hosts_allow} = '192.168.1.1';
+ __PACKAGE__->config->{scheduler}->{hosts_allow} = [
+ '127.0.0.1',
+ '192.168.1.1'
+ ];
+
+SCHEDULING
+ AUTOMATED EVENTS
+ Events are scheduled by calling the class method "schedule".
+
+ MyApp->schedule(
+ at => '0 * * * *',
+ event => '/cron/remove_sessions',
+ );
+
+ package MyApp::Controller::Cron;
+
+ sub remove_sessions : Private {
+ my ( $self, $c ) = @_;
+
+ $c->delete_expired_sessions;
+ }
+
+ at
+ The time to run an event is specified using crontab(5)-style syntax.
+
+ 5 0 * * * # 5 minutes after midnight, every day
+ 15 14 1 * * # run at 2:15pm on the first of every month
+ 0 22 * * 1-5 # run at 10 pm on weekdays
+ 5 4 * * sun # run at 4:05am every Sunday
+
+ From crontab(5):
+
+ field allowed values
+ ----- --------------
+ minute 0-59
+ hour 0-23
+ day of month 1-31
+ month 0-12 (or names, see below)
+ day of week 0-7 (0 or 7 is Sun, or use names)
+
+ Instead of the first five fields, one of seven special strings may
+ appear:
+
+ string meaning
+ ------ -------
+ @yearly Run once a year, "0 0 1 1 *".
+ @annually (same as @yearly)
+ @monthly Run once a month, "0 0 1 * *".
+ @weekly Run once a week, "0 0 * * 0".
+ @daily Run once a day, "0 0 * * *".
+ @midnight (same as @daily)
+ @hourly Run once an hour, "0 * * * *".
+
+ event
+ The event to run at the specified time can be either a Catalyst private
+ action path or a coderef. Both types of event methods will receive the
+ $c object from the current request, but you must not rely on any
+ request-specific information present in $c as it will be from a random
+ user request at or near the event's specified run time.
+
+ Important: Methods used for events should be marked "Private" so that
+ they can not be executed via the browser.
+
+ auto_run
+ The auto_run parameter specifies when the event is allowed to be
+ executed. By default this option is set to 1, so the event will be
+ executed during the first request that matches the specified time in
+ "at".
+
+ If set to 0, the event will only run when a request is made by a user
+ from an authorized address. The purpose of this option is to allow
+ long-running tasks to execute only for certain users.
+
+ MyApp->schedule(
+ at => '0 0 * * *',
+ event => '/cron/rebuild_search_index',
+ auto_run => 0,
+ );
+
+ package MyApp::Controller::Cron;
+
+ sub rebuild_search_index : Private {
+ my ( $self, $c ) = @_;
+
+ # rebuild the search index, this may take a long time
+ }
+
+ Now, the search index will only be rebuilt when a request is made from a
+ user whose IP address matches the list in the "hosts_allow" config
+ option. To run this event, you probably want to ping the app from a cron
+ job.
+
+ 0 0 * * * wget -q http://www.myapp.com/
+
+ MANUAL EVENTS
+ To create an event that does not run on a set schedule and must be
+ manually triggered, you can specify the "trigger" option instead of
+ "at".
+
+ __PACKAGE__->schedule(
+ trigger => 'send_email',
+ event => '/events/send_email',
+ );
+
+ The event may then be triggered by a standard web request from an
+ authorized user. The trigger to run is specified by using a special GET
+ parameter, 'schedule_trigger'; the path requested does not matter.
+
+ http://www.myapp.com/?schedule_trigger=send_email
+
+ By default, manual events may only be triggered by requests made from
+ localhost (127.0.0.1). To allow other addresses to run events, use the
+ configuration option "hosts_allow".
+
+SCHEDULING USING A YAML FILE
+ As an alternative to using the schedule() method, you may define
+ scheduled events in an external YAML file. By default, the plugin looks
+ for the existence of a file called "schedule.yml" in your application's
+ home directory. You can change the filename using the configuration
+ option "yaml_file".
+
+ Modifications to this file will be re-read once per minute during the
+ normal event checking process.
+
+ Here's an example YAML configuration file with 4 events. Each event is
+ denoted with a '-' character, followed by the same parameters used by
+ the "schedule" method. Note that coderef events are not supported by the
+ YAML file.
+
+ ---
+ - at: '* * * * *'
+ event: /cron/delete_sessions
+ - event: /cron/send_email
+ trigger: send_email
+ - at: '@hourly'
+ event: /cron/hourly
+ - at: 0 0 * * *
+ auto_run: 0
+ event: /cron/rebuild_search_index
+
+SECURITY
+ All events are run inside of an eval container. This protects the user
+ from receiving any error messages or page crashes if an event fails to
+ run properly. All event errors are logged, even if logging is disabled.
+
+PLUGIN SUPPORT
+ Other plugins may register scheduled events if they need to perform
+ periodic maintenance. Plugin authors, be sure to inform your users if
+ you do this! Events should be registered from a plugin's "setup" method.
+
+ sub setup {
+ my $c = shift;
+ $c->NEXT::setup(@_);
+
+ if ( $c->can('schedule') ) {
+ $c->schedule(
+ at => '0 * * * *',
+ event => \&cleanup,
+ );
+ }
+ }
+
+CAVEATS
+ The time at which an event will run is determined completely by the
+ requests made to the application. Apps with heavy traffic may have
+ events run at very close to the correct time, whereas apps with low
+ levels of traffic may see events running much later than scheduled. If
+ this is a problem, you can use a real cron entry that simply hits your
+ application at the desired time.
+
+ 0 * * * * wget -q http://www.myapp.com/
+
+ Events which consume a lot of time will slow the request processing for
+ the user who triggers the event. For these types of events, you should
+ use auto_run => 0 or manual event triggering.
+
+PERFORMANCE
+ The plugin only checks once per minute if any events need to be run, so
+ the overhead on each request is minimal. On my test server, the
+ difference between running with Scheduler and without was only around
+ 0.02% (0.004 seconds).
+
+ Of course, when a scheduled event runs, performance will depend on
+ what's being run in the event.
+
+METHODS
+ schedule
+ Schedule is a class method for adding scheduled events. See the
+ "SCHEDULING"" in " section for more information.
+
+ scheduler_state
+ The current state of all scheduled events is available in an easy-to-use
+ format by calling $c->scheduler_state. You can use this data to build an
+ admin view into the scheduling engine, for example. This same data is
+ also displayed on the Catalyst debug screen.
+
+ This method returns an array reference containing a hash reference for
+ each event.
+
+ [
+ {
+ 'last_run' => '2005-12-29 16:29:33 EST',
+ 'auto_run' => 1,
+ 'last_output' => 1,
+ 'at' => '0 0 * * *',
+ 'next_run' => '2005-12-30 00:00:00 EST',
+ 'event' => '/cron/session_cleanup'
+ },
+ {
+ 'auto_run' => 1,
+ 'at' => '0 0 * * *',
+ 'next_run' => '2005-12-30 00:00:00 EST',
+ 'event' => '/cron/build_rss'
+ },
+ ]
+
+INTERNAL METHODS
+ The following methods are extended by this plugin.
+
+ dispatch
+ The main scheduling logic takes place during the dispatch phase.
+
+ dump_these
+ On the Catalyst debug screen, all scheduled events are displayed
+ along with the next time they will be executed.
+
+ setup
+
+SEE ALSO
+ crontab(5)
+
+AUTHOR
+ Andy Grundman, <andy at hybridized.org>
+
+COPYRIGHT
+ This program is free software, you can redistribute it and/or modify it
+ under the same terms as Perl itself.
+
Property changes on: trunk/Catalyst-Plugin-Scheduler/README
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: trunk/Catalyst-Plugin-Scheduler/lib/Catalyst/Plugin/Scheduler.pm
===================================================================
--- trunk/Catalyst-Plugin-Scheduler/lib/Catalyst/Plugin/Scheduler.pm 2008-01-12 15:19:42 UTC (rev 7375)
+++ trunk/Catalyst-Plugin-Scheduler/lib/Catalyst/Plugin/Scheduler.pm 2008-01-12 15:51:06 UTC (rev 7376)
@@ -11,7 +11,7 @@
use Set::Scalar;
use Storable qw/lock_store lock_retrieve/;
-our $VERSION = '0.07';
+our $VERSION = '0.08';
__PACKAGE__->mk_classdata( '_events' => [] );
__PACKAGE__->mk_accessors('_event_state');
@@ -157,6 +157,20 @@
$c->config->{scheduler}->{state_file} ||= $c->path_to('scheduler.state');
$c->config->{scheduler}->{hosts_allow} ||= '127.0.0.1';
$c->config->{scheduler}->{yaml_file} ||= $c->path_to('scheduler.yml');
+
+ # Always start with a clean state
+ if ( -e $c->config->{scheduler}->{state_file} ) {
+ $c->log->debug(
+ 'Scheduler: Removing old state file ' .
+ $c->config->{scheduler}->{state_file}
+ ) if $c->config->{scheduler}->{logging};
+
+ unlink $c->config->{scheduler}->{state_file}
+ or Catalyst::Exception->throw(
+ message => 'Scheduler: Unable to remove old state file '
+ . $c->config->{scheduler}->{state_file} . " ($!)"
+ );
+ }
$c->NEXT::setup(@_);
}
More information about the Catalyst-commits
mailing list