Scheduling php scripts

只愿长相守 提交于 2019-11-29 08:02:49

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.

$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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!