Tâches périodiques en plusieurs lots et valeur à retourner : quid ?

Selon la doc sur programmer, Il est possible d’exécuter une tâche périodique en plusieurs lots pour éviter les timeout.
Pour ce faire on peut lui dire de se relancer en retournant un entier négatif.

Jusque là tout va bien, j’arrive à suivre.
Par contre, je suis pas sûr de comprendre quelle valeur il faut donner en retour selon les cas de figures, je pige pas l’explication dans la doc.

Au départ on avait ceci :

Dans ce cas là, le nombre négatif indiqué correspond au nombre de secondes d’intervalle pour la prochaine exécution.

Puis ça a été modifié en novembre 2020 comme ça :

Dans ce cas là, la valeur absolue du nombre négatif indiqué correspond au timestamp de la dernière exécution de la tâche à partir duquel doit s’appliquer le délai spécifié dans le plugin taches_generales_cron pour définir le moment de la prochaine exécution

Ça semble dire 2 choses différentes, je suis perdu.
En mettant mon nez dans le code de certains plugins et leurs commentaires, je comprends ceci pour l’instant :

  • Pour relancer tout de suite, on garde le même timestamp : return (0 - $t) (exemple mailshot)
  • Pour relancer tout de suite mais avec une plus grande priorité, on met un timestamp plus petit, par ex. : return -($t - 10) (exemple mailshot)
  • Et j’en déduis que pour relancer dans le futur, on incrémente le timestamp : return -($t + 10)

Est-ce que c’est bien ça ?

Le 23/08/2021 à 11:52, tcharlss via Discuter de SPIP a écrit :

[tcharlss] tcharlss https://discuter.spip.net/u/tcharlss
Août 23

Selon la doc sur programmer https://programmer.spip.net/Declarer-une-tache, Il est possible d’exécuter une tâche
périodique en plusieurs lots pour éviter les timeout.
Pour ce faire on peut lui dire de se relancer en retournant un entier négatif. Jusque là tout va bien, j’arrive à
suivre. Par contre, je suis pas sûr de comprendre quelle valeur il faut donner en retour selon les cas de figures,
je pige pas l’explication dans la doc. Au départ on avait ceci :

Dans ce cas là, le nombre négatif indiqué correspond au nombre de secondes d’intervalle pour la prochaine exécution.

Puis ça a été modifié en novembre 2020 comme ça :

Dans ce cas là, la valeur absolue du nombre négatif indiqué correspond au timestamp de la dernière exécution de la
tâche à partir duquel doit s’appliquer le délai spécifié dans le plugin taches_generales_cron pour définir le
moment de la prochaine exécution

Ça semble dire 2 choses différentes, je suis perdu.

Ben oui, c’est normal que ça soit différent car j’ai changé pour corriger.
Il m’avait fallu explorer pour obtenir des déclenchements à des heures précises et mon code actuel a validé ces
explications.
Quelque chose n’est pas clair dans l’explication ?

Comme c’est pas des plus simples à mettre en œuvre, j’ai une petite fonction helper qui aide bien pour certains besoins.

Mais dans tous les cas il faut savoir que sur un site derrière un varnish ou sur un site avec peu de fréquentation,
l’heure programmée pour le déclenchement ne peut être qu’approximative.
JLuc

Voici la fonction helper pour viser une heure spécifique de déclanchement. 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 heuire
  • ç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).
// 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 > 0, la valeur précise est ignorée, c'est juste relancé avec le délai du pipeline
// Quand c'est négatif, la valeur absolue renvoyée indique l'heure considérée comme étant celle de la dernière exécution
// à 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, 0, 0);
// @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 (0 - ($h_debut_cejour - 24 * 3600)); // on veut que ce soit aujourd'hui donc on compense le délai normal de 24h
} 

Le 23/08/2021 à 22:37, JLuc via Discuter de SPIP a écrit :

[JLuc] JLuc https://discuter.spip.net/u/jluc
Août 23

Voici la fonction helper pour viser une heure spécifique de déclanchement.

Serait il utile de reporter cette fonction comme exemple
dans la page de doc ?

JL

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 heuire
  • ç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).

|// 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 > 0, la valeur précise est ignorée, c’est
juste relancé avec le délai du pipeline // Quand c’est négatif, la valeur absolue renvoyée indique l’heure considérée
comme étant celle de la dernière exécution // à 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, 0, 0); // @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 (0 - ($h_debut_cejour -

24 * 3600)); // on veut que ce soit aujourd’hui donc on compense le délai normal de 24h }

ça me parait une mauvaise idée de reporter cette fonction dans la doc car

  • elle peut faire croire qu’il y a un moyen fiable de déclencher les crons à heure fiable et ce n’est pas le cas. Si tu as pas de visites sur ton site dans le créneau horaire visé il se passera rien
  • elle ne marche que sur des cas précis d’après les commentaires et donc ça va inévitablement générer du support d’utilisateurs qui l’utilisent dans d’autres cas

Par contre il peut être opportun d’améliorer la doc, et peut-être d’illustrer des cas précis les plus courants

Il serait peut être opportun d’améliorer la doc, et peut-être d’illustrer des cas précis les plus courants

Oui c’est surtout ça qui manque je pense pour clarifier les choses : des exemples simples.

Dans le cas d’une tâche séparée en plusieurs lots, couramment on réfléchit en terme de délai entre l’exécution de 2 lots. Les exemples pourraient être ça :

  1. Aucun délai : on veut que les lots s’exécutent les uns à la suite des autres dès que possible. J’ai cru comprendre qu’il est possible d’affiner la priorité de la prochaine exécution en donnant un timestamp plus petit que l’actuel (mais je suis pas sûr).
  2. Un délai de N secondes

L’exemple donné par @JLuc me semble correspondre à un cas plus particulier. Ça pourrait être donné en exemple mais à part, comme un exemple avancé.

Le 26/08/2021 à 15:51, cerdic via Discuter de SPIP a écrit :

[cerdic] cerdic
Août 26

ça me parait une mauvaise idée de reporter cette fonction dans la doc car

  • elle peut faire croire qu’il y a un moyen fiable de déclencher les crons à heure fiable et ce n’est pas le cas. Si
    tu as pas de visites sur ton site dans le créneau horaire visé il se passera rien

En effet, et j’ai exprimé ces réserves « plus haut ». Mais ça n’enlève rien à l’intéret d’une telle fonction car SPIP a
privilégié les délais et la déclaration d’une périodicité, plutôt que la déclaration d’heures de déclenchements. Les
imprécisions que tu relèves s’additionnant chaque jour, si on commence à 21h avec un délai de 24h, on peut bien se
retrouver à 9h30 quelques jours, semaines ou mois après. La fonction citée ne garantit pas la précision du
déclenchement, mais elle évite les décalages progressivement de plus en plus importants par rapport à une heure fixe
dans la journée.

  • elle ne marche que sur des cas précis d’après les commentaires et donc ça va inévitablement générer du support
    d’utilisateurs qui l’utilisent dans d’autres cas

Par contre il peut être opportun d’améliorer la doc, et peut-être d’illustrer des cas précis les plus courants

Note que vouloir déclencher une tâche « tous les jours à 21h (par exemple) » me semble un cas très banal et assez courant. Le fait de prolonger par lot n’est pas requis pour pouvoir se servir de cette fonction, mais il se trouve que c’était aussi le besoin de Tcharlss.

J’ai créé une page sur le carnet pour collecter vos autres cas précis courants :
https://contrib.spip.net/Valeurs-de-retour-d-un-cron-fonction-pour-taches
Donc à vos contributions !

JLuc

J’ai simplifié l’exemple sur Valeurs de retour d’un cron (fonction pour tâches périodiques)
Il n’y a pas encore d’autres contribution mais celle ci me semble présentable déjà.