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)
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
}
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 :
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).
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.