Le principe est le suivant :
- Les taches sont des classes
- Les taches sont séquentielles
- On demande une fois à la tache quand elle veut s'activer puis on y
touche plus jusqu'à l'activation.
- Le déclenchement peut être irrégulier
- En cas d'echec, on peut recommencer dans un petit laps de temps.
Un utilitaire "chronomètre" permet de simplement manipuler les
fréquences de répétition des taches.
Ce système est proposé pour pallier aux soucis de lock du système actuel
et pour ne pas avoir à refaire à chaque fois des calculs de dates. Il
semble aussi y avoir des taches qui ne se déclenche pas dans la liste.
Améliorations possibles :
- gestion de cache pour ne pas faire des calculs qui disent de ne rien
faire à chaque passage.
- utilisation d'un dossier des "taches" pour pouvoir empiler
tranquilement ses taches avec celles de Spip.
8<-------------------------------------------------------------------------------------------------------------------------------
<?php
/*
* Created on 13 nov. 2004
*/
/**
* pulsation declenchée par une url ou autre
*/
function spip_tick(){
$lock = '/tmp/spip_cron.lock';
if((time() - @filemtime($lock)) > 30){//le tic est non threadé, et a
un minimum de 30 secondes
touch($lock);
$sql = "SELECT * FROM spip_crons WHERE date < NOW() ORDER BY date";
$r = spip_query($sql);
if($ligne = spip_fetch_array($r)){
$tache = new $ligne['action'];
if($tache->action())
$t = $tache->prochaine_fois();
else
$t = $tache->prochain_essai();
$t = max($t,time()); //on vérifie qu'il n'y a pas d'antidatage
$date = unix2sql($t);
$sql = "UPDATE spip_crons SET date='$date' WHERE
action='$ligne[action]'";
spip_query($sql);
}
}
}
/**
* @param Integer $t timestampe UNIX
* @return String date au format SQL
*/
function unix2sql($t){
return date('Y-m-j H:m:s',$t);
}
/**
* mise en place des taches dans la base de donnée
*/
function initialisation(){
$liste = array('tache_1','tache_2');
spip_query('TRUNCATE spip_crons');
foreach($liste as $tache){
$t = new $tache;
$date = unix2sql($t->prochaine_fois());
$sql = "INSERT INTO spip_crons (action,date) VALUES
('$tache','$date')";
echo $sql;
$r = spip_query($sql);
}
}
/**
* Tache de base
* @author mlecarme@linagora.com
*/
class tache{
/**
* tentative en cas d'echec de l'action
* @return Integer timestamp UNIX
*/
function prochain_essai(){
return time()+ 5*60;
}
/**
* prochaine action si tout c'est bien passé avant
* @return Integer timestamp UNIX
*/
function prochaine_fois(){
return time()+ 15*60;
}
/**
* action que doit effectuer la "tache"
* @return Boolean l'action a-t-elle réussit?
*/
function action(){
return true;
}
}
/**
* Class chronomètre pour manipuler des timestamps
* @author mlecarme@linagora.com
*/
class chronometre{
/**
* Par défaut on utilise le timestamp courant
*/
function chronometre(){
$this->t = time();
}
/**
* regler le chronomètre
* @param Integer un timestamp arbitraire
*/
function regler($t){
$this->t = $t;
}
/**
* @param Integer $h heure
* @param Integer $m minute
* @param Integer $s seconde
*/
function ajoute($h,$m=0,$s=0){
$this->t += ($h * 60 + $m) * 60 + $s;
}
/**
* @param Integer jours à ajouter
*/
function ajoute_jour($j){
$this->t += 60 * 60 * 24 * $j;
}
/**
* @return Integer timestamp
*/
function valeur(){
return $this->t;
}
/**
* regle le chronometre sur le prochain jour $j de la semaine
* @param String nom du jour
*/
function jour_de_la_semaine($j){
$jours =
array('dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi');
$n = array_search($j,$jours);
$w = date('w',time());
$delta = ($n-$w+7) % 7;
//if(! $delta)
// $delta += 7;
$this->ajoute_jour($delta);
}
/**
* règle le chronomètre sur minuit.
*/
function a_minuit(){
$h = date('G',$this->t);
$m = date('i',$this->t);
$s = date('s',$this->t);
$this->t -= (($h * 60) + $m)* 60 + $s;
}
function debug(){
echo (date('r',$this->t))."\n";
}
}
class tache_quoideneuf extends tache{
function prochaine_fois(){
$c = new chronometre();
$c->a_minuit();
$c->ajouter_jour(lire_meta('jours_neuf'));
}
function action(){
//flemme
return true;
}
}
class tache_1 extends tache {
function action(){
print 'tache n°1';
spip_log('tache n° 1');
return true;
}
}
class tache_2 extends tache {
function action(){
print 'tache n°2';
spip_log('tache n° 2');
return true;
}
}
?>
8<---------------------------------------------------------------------------------------------------