[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