开发者

Scheduling php scripts

I want to create some function to schedule php scripts,for example if i want tu run page.php at 12/12/2012 12:12 i can call

schedule_script('12/12/2012 12:12','page.php');//or by passing a time/datetime object

or for example call one script every minute

schedule_interval(60,'page.php');//every 60s=1minute

i'll may add some other function to see what script are scheduled or delete one of them.

i want this functions to work on both UNIX and WINDOWS platforms,i DO NOT want ugly solutions like executing a script on every page o开发者_如何学运维f the site(i want to schedule this commands when nobody is on the site) or using "buisy wait" implementations ( using sleep() on a script that checks if there are any scheduled jobs) or something that require user intervention(like write something in console or open a panel).

I found the "AT" command on MSDOS(works well on all windows)but it's very basic because it accept only time and not dates,there's a more powerful version on UNIX but i don't know how to use it(and i want a solution for both platforms).


There's a PHP function which lets you delay script execution till a point in time.

So let's say I have cron.php:

<?php

   // Usage:
   //    cron.php [interval|schedule] [script] [interval|stamp]
   if(!isset($argc) || count($argc)!=2)die; // security precaution

   $time=(int)$argv[3]; // just in case :)

   if($argv[1]=='schedule'){
       time_sleep_until((int)$_GET['until']);
       include_once($time);
   }elseif($argv[1]=='interval')
       while(true){ // this is actually an infinite loop (you didn't ask for an "until" date? can be arranged tho)
           usleep($time*1000); // earlier I said milliseconds: 1000msec is 1s, but this func is for microseconds: 1s = 1000000us
           include_once($argv[2]);
       }

?>

And your classes/functions file:

// Const form K2F - Are we on windows?
define('ISWIN', strpos(strtolower(php_uname()),'win')!==false &&
                strpos(strtolower(php_uname()),'darwin')===false );

// Function from K2F - runs a shell command without waiting (works on all OSes)
function run($cmd){
    ISWIN ? pclose(popen('start /B '.$cmd,'r')) : exec($cmd.' > /dev/null &');
}

script_schedule($script,$time){
    if(is_string($time))$time=strtotime($time);
    run('php -f -- schedule '.escapeshellarg($script).' '.$time);
}

script_interval($script,$mseconds){
    run('php -f -- interval '.escapeshellarg($script).' '.$mseconds);
}

It ought to work. By the way, K2F is this framework that makes your dreams come true..faster. ;). Cheers.

Edit: If you still want the parts about counting running jobs and/or deleting(stopping) them, I can help you out with it as well. Just reply to my post and we'll follow up.


This is my implementation of the scheduler,i need only to launch it if isn't active and add all jobs on the mysql job table(i already have one for my main script),this script will launch all jobs ready to be executed(the sql table have a datetime field).

What i call "Mutex" is a class that tells if one or more than one copy of the script is running and can even send commands to the running script throught a pipe(you simply have to create a new mutex with the same name for all the scripts)so you can even stop a running script from another script.

<?php
//---logging---
$logfile = dirname(dirname(__FILE__)).'/scheduler.log';
$ob_file = fopen($logfile,'a');
function ob_file_callback($buffer)
{
  global $ob_file;
  fwrite($ob_file,$buffer);
}




//--includes---

  $inc=dirname(dirname(__FILE__)).'/.include/';
  require_once($inc.'Mutex.php');
  require_once($inc.'jobdb.php');
//--mutex---
//i call it mutex but it's nothing like POSIX mutex,it's a way to synchronyze scripts
  $m=new Mutex('jscheduler');
  if(!$m->lock())//if this script is already running
    exit();//only one scheduler at time
//---check loop---
  set_time_limit(-1);//remove script time limit
  for(;;){
      ob_start('ob_file_callback');//logging 

     $j=jobdb_get_ready_jobs(true);//gets all ready jobs,works with mysql
     if($j!=null)//found some jobs
         foreach($j as $val){//run all jobs

            $ex='*SCRIPT NAME AND PARAMETERS HERE*';

            if(!run_script($ex))
                echo "UNABLE TO LAUNCH THE JOB!\n";
        }
     $n=($j!=null)?count($j).'JOBS LAUNCHED':'NO JOBS';


     sleep(60);
     if($m->has_to_stop())//yeah,i can stop this script from other scripts,it works with a file pipeline
        exit("# STOPPING SCHEDULER\n");            

     ob_end_flush();//LOGGING  
  }

?>

My "run_script" function works the same way as the Sciberras "run" function.

To activate the scheduler you should simply use this command

 run_script('scheduler.php');

to check if it's active

$m=new Mutex('jscheduler');
if(!$m->test_lock())
    echo 'SCHEDULER IS ACTIVE';
else 
    echo 'SCHEDULER IS INACTIVE';

and to stop the scheduler

$m=new Mutex('jscheduler'); 
$m->ask_to_stop();//simply sent throught the pipe the command,now has_to_stop()will return true on the process that have gain the lock of the mutex
echo 'STOPPING SCHEDULER...';

i may have gone way too far on his implementation,anyway there may be a problem of "lag",for example if the scheduler starts at 0:00.00 and i have two scripts at 0:01.01 and 0:01.59 both are launched at 0:02.0 . To fix this "lag" i'll may retreive all the jobs scheduled in the next minute and schedule them like in the Sciberras code using time_sleep_until. This will not create too many running threads(i may want to test if there's a limit or a performance drop on launching a HUDGE amount of threads but i'm sure there will be some problems)and ensures perfect timing requiring only to check if the scheduler is active.


$amt_time = "1";
$incr_time = "day";
$date = "";
$now=  ''. date('Y-m-d') ."";   
if (($amt_time!=='0') && ($incr_time!=='0')) {
$date = strtotime(date("Y-m-d".strtotime($date))."+$amt_time $incr_time");
$startdate=''.date('Y-m-d',$date) ."";
} else {
$startdate="0000-00-00";
}
if ($now == $startdate) {
include ('file.php');
}

Just a guess ;) Actually I might have it in reverse but you get the idea

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜