Carnet Wiki

Valeurs de retour d’un cron (fonction pour tâches périodiques)

Version 4 — Août 2021 JLuc

La documentation https://programmer.spip.net/Declarer-une-tache présente comment déclarer une tâche cron et sa périodicité.

La fonction implémentant un cron doit renvoyer une valeur dont le calcul n’est pas évident dans certains cas.

Cette page vise à collecter des exemples de calculs.

Rappel

(Voir [->https://programmer.spip.net/100] )
La date du prochain cron dépend de la valeur renvoyée par le génie ET de la déclaration de délais faite dans le pipeline taches_generales_cron.
- <code class=« php  »>
// La date du prochain cron dépend de la valeur renvoyée par le génie
//
ET de la déclaration de délais faite dans le pipeline taches_generales_cron
//
Quand la valeur renvoyée par le génie est positive > , la valeur précise est ignorée, c’est juste relancé avec le délai du pipeline
-  

//
Quand elle est négative c’est négatif , la valeur absolue renvoyée indique l’heure considérée par le génie comme étant celle de la dernière exécution et
//
à partir de laquelle va s’appliquer le délai spécifié dans le pipeline.
//
Si le résultat est déjà dépassé , c’est programmé pour être exécuté tt de suite ( dés que possible )
// Sinon ça prend la queue
//

//
genie_vise_heure calcule la valeur de retour permettant une exécution du génie chaque jour à la même heure
//
Les calculs ne marchent que pour une plage horaire nocturne ( h_début < minuit , h_fin > minuit )
//
// @param $ h_debut_cejour = mktime(CHAQUE_JOUR_H_DEBUT , , ) ;
// @return valeur utilisable comme valeur de retour du genie
function genie_vise_heure($h_debut_cejour )
$now = time () ;
// $h_debut_cejour c’est 23h le même jour ,
// donc dans le passé il y a peu s’il est plus de 23h , mais dans 22h s’il est 1h du mat
if ($ now > $ h_debut_cejour )
// S’il est entre 23h et minuit , quand ce sera fini il faudra que ça se relance «  demain  »
// et donc garder le délai de 24h par rapport à 23h à ce soir
return ( 0-$h_debut_cejour ) ;

//
sinon , par exemple il est 5h du mat ou 10h , on relance le soir même à 23h ,
// et donc il faut compenser le délai de 24h déjà ajouté à 23h ce soir
return ( - ($ h_debut_cejour - 24 * 3600 )) ; // on veut que ce soit aujourd’hui donc on compense le délai normal de 24h

</
code > Et si le résultat est déjà dépassé, c’est programmé pour être exécuté tout de suite (dés que possible). Sinon ça prend la queue.

Déclenchement chaque jour à la même heure environ

L’API pour les tâches cron permet de facilement déclarer des périodicités pour les déclenchements, mais il est plus délicat de déclarer des heures de déclenchements fixes chaque jour.

Voici une fonction qui aide à viser une heure fixe pour le déclenchement d’une tâche chaque jour J à une heure HH (exemple : 23).
-  Comme c’est un lancement quotidien, le délai pour ce cron est de 24h.
-  Dans le code, la constante CHAQUE_JOUR_H_DEBUT vaut l’heure de déclenchement HH.
Exemple : define ('CHAQUE_JOUR_H_DEBUT', 23);
-  Le jour suivant J+1, un nouveau lancement doit se faire à la même heure HH visée environ, sans que le décalage de J ne s’ajoute au nouveau décalage de J+1.

l’API pour les tâches cron permet de facilement déclarer des périodicités pour les déclanchements, mais il est plus délicat de déclarer des heures de déclenchements fixes chaque jour. Voici une fonction qui aide à viser une heure spécifique pour le déclenchement d’une tâche.
Cette Attention  : cette fonction évite les dérives progressives en recalant le déclenchement chaque jour, mais elle ne garantit pas que le un déclenchement se fasse précisément précis à l’heure programmée, car cela dépend de la fréquentation du site : sur un site sans fréquentation la tâche ne se déclenchera pas, sur un site ayant une faible fréquentation, elle se déclenchera en retard.

/**
 * genie_vise_heure calcule la valeur de retour permettant une exécution du génie 
 * chaque jour à la même heure environ
 * @param $h_debut_cejour = mktime(CHAQUE_JOUR_H_DEBUT, 0, 0);  =HH, par ex 23
 * @return valeur utilisable comme valeur de retour du genie 
*/
function genie_vise_heure($h_debut_cejour) {
  $now = time();
  // $h_debut_cejour c'est l'heure de début visée du même jour,
  // ça peut être déjà passé ou pas encore
  if ($now > $h_debut_cejour) {
    // Si c'est passé, il faudra relancer "demain"
    // et donc on garde le délai de 24h par rapport à HH à ce soir
    return (0-$h_debut_cejour);
  }
  // sinon, c'est qu'il y a eu un grand retard
  // on veut relancer le jour même à HH environ
  // et donc il faut compenser le délai de 24h déjà ajouté à HH ce soir
  return (0 - ($h_debut_cejour - 24 * 3600)); 
} 

Le scénario dans lequel je m’en sers est le suivant :

- lancement initial à une heure visée, avant minuit du J1 (exemple : 23h)
-  suite des lots pour éviter les timeout en utilisant queue_lancer_url_http_async() la nouvelle fonction du core pour lancer des url en asynchrone
-  ça peut s’interrompre à tout moment mais au plus tard le lendemain J+1 à une certaine heure
-  ça doit reprendre le soir de J+1 à la même heure qu’en J (et sans que des décalages ne puissent s’ajouter chaque jour).