[Catalyst] Patch (was: Scheduler Plugin localizing)

Bill Moseley moseley at hank.org
Wed May 31 06:43:54 CEST 2006


Here's another patch.

This one includes the "fix" to localizing the response objects before
calling the scheduled task.

Also, fixed the problem of it not reloading the scheduler.yml file on
the restarting test server.

Added "require_path" config option and "require_path" event option.
This says to not fire the scheduled events except when the request is
for a specific path.  Useful for cron to trigger long-running tasks
instead of a general (user-generated) request.

There was already the auto_run feature to limit what hosts would
trigger the events.  For example, you could use auto_run to limit
some events to be triggered by only requests from localhost.

But, if, for example, the event results in an email that includes
URLs they will point to localhost.


-- 
Bill Moseley
moseley at hank.org

-------------- next part --------------
Index: lib/Catalyst/Plugin/Scheduler.pm
===================================================================
--- lib/Catalyst/Plugin/Scheduler.pm	(revision 4247)
+++ lib/Catalyst/Plugin/Scheduler.pm	(working copy)
@@ -12,7 +12,7 @@
 use Storable qw/lock_store lock_retrieve/;
 use YAML;
 
-our $VERSION = '0.06';
+our $VERSION = '0.07';
 
 __PACKAGE__->mk_classdata( '_events' => [] );
 __PACKAGE__->mk_accessors('_event_state');
@@ -31,6 +31,7 @@
         trigger  => $args{trigger},
         event    => $args{event},
         auto_run => ( defined $args{auto_run} ) ? $args{auto_run} : 1,
+        require_path => $args{require_path},
     };
 
     if ( $args{at} ) {
@@ -65,11 +66,13 @@
 
     $c->_check_yaml();
 
+
     # check if a minute has passed since our last check
     # This check is not run if the user is manually triggering an event
     if ( time - $c->_event_state->{last_check} < 60 ) {
         return unless $c->req->params->{schedule_trigger};
     }
+
     my $last_check = $c->_event_state->{last_check};
     $c->_event_state->{last_check} = time;
     $c->_save_event_state();
@@ -85,6 +88,7 @@
     for my $event ( @{ $c->_events } ) {
         my $next_run;
 
+
         if (   $event->{trigger} && $c->req->params->{schedule_trigger}
             && $event->{trigger} eq $c->req->params->{schedule_trigger} )
         {
@@ -95,11 +99,21 @@
         }
         else {
             next EVENT unless $event->{set};
+
+            my $cur_path = $c->req->path;
+
+            # Require specific path to run for timed events (i.e. non-trigger)
+            next EVENT if $conf->{require_path} && $conf->{require_path} ne $cur_path;
+
+            # Can limit by event, too
+            next EVENT if $event->{require_path} && $event->{require_path} ne $cur_path;
+
             $next_run = $event->{set}->next($last_check_dt);
         }
 
         if ( $next_run <= $now ) {
 
+
             # do some security checking for non-auto-run events
             if ( !$event->{auto_run} ) {
                 next EVENT unless $c->_event_authorized;
@@ -114,7 +128,7 @@
 
             # trap errors
             local $c->{error} = [];
-            
+
             # return value/output from the event, if any
             my $output;
 
@@ -122,12 +136,10 @@
             eval {
 
                 # do not allow the event to modify the response
-                local $c->res->{body};
-                local $c->res->{cookies};
-                local $c->res->{headers};
-                local $c->res->{location};
-                local $c->res->{status};
 
+                # do not allow the event to modify the response
+                local $c->res->{$_} = $c->res->{$_} for qw/ body cookies headers location status/;
+
                 if ( ref $event->{event} eq 'CODE' ) {
                     $output = $event->{event}->($c);
                 }
@@ -243,9 +255,11 @@
 
     return unless -e $c->config->{scheduler}->{yaml_file};
 
+
     eval {
         my $mtime = ( stat $c->config->{scheduler}->{yaml_file} )->mtime;
-        if ( $mtime > $c->_event_state->{yaml_mtime}->{$$} ) {
+
+        if ( ($mtime > $c->_event_state->{yaml_mtime}->{$$}) || !@{$c->_events} ) {
             $c->_event_state->{yaml_mtime}->{$$} = $mtime;
 
             # clean up old PIDs listed in yaml_mtime
@@ -503,6 +517,19 @@
         '192.168.1.1'
     ];
 
+=head2 require_path
+
+This can be set to a specific path and only a request that matches this path exactly
+will cause events to be triggered.
+
+For example:
+
+    MyApp->config->{scheduler}->{require_path} = 'ping';
+
+Then only requests to /ping (relative to base) will trigger scheduled events.
+This has no affect on manual events.
+
+
 =head1 SCHEDULING
 
 =head2 AUTOMATED EVENTS
@@ -594,6 +621,21 @@
 
     0 0 * * * wget -q http://www.myapp.com/
 
+=head3 require_path
+
+This parameter can be used to limit what request will trigger a scheduled
+event.  The value provided is matched against the request path, relative to base.
+
+    MyApp->schedule(
+        at           => '*/5 * * * *',
+        event        => '/cron/clean_carts',
+        require_path => 'ping',
+    );
+
+Only requests to /ping (relative to the Catalyst base) will trigger the event.
+This has no affect on manual events.
+
+
 =head2 MANUAL EVENTS
 
 To create an event that does not run on a set schedule and must be manually
Index: Changes
===================================================================
--- Changes	(revision 4247)
+++ Changes	(working copy)
@@ -1,5 +1,14 @@
 Revision history for Perl extension Catalyst::Plugin::Scheduler
 
+0.07
+        - Added "require_path" to both the config and to the events
+          to limit what requests will trigger the events.
+        - When running under Engine::HTTP::Reloader didn't detect
+          the restart and would not reload the YAML file.  Now,
+          always tries to reload the YAML file if no events are defined.
+        - Sets localized $c->res objects back to their value so they 
+          are not undefined when running the scheduled task.
+
 0.06    2006-03-10 10:10:00
         - Added $c->scheduler_state public method to allow users to
           build admin screens detailing the current status of every


More information about the Catalyst mailing list