Pour un site Web de grande institution, avec des caches lourds, j'aimerais générer des caches dès que possible, afin qu'aucun utilisateur ne puisse arriver lors de la génération du cache ...
J'ai un cron défini toutes les minutes qui le fait, en exécutant quelques fonctions et en demandant des pages critiques, mais ce que je cherche, c'est un moyen de savoir quand le cache vient d'être effacé , de préférence un hook, donc je peux lancer ce fonctions de génération.
Une idée ?
Réponses:
Il n'y en a pas dans Drupal 7.x mais cela a été ajouté en tant que hook principal, hook_rebuild dans Drupal 8.x après que suffisamment de personnes l' aient demandé. Il y a peut-être un meilleur moyen de résoudre votre problème dans 7.x - vous essayez d'initier une sorte de fonctionnalité de réchauffement du cache juste après que cron a effacé le cache, n'est-ce pas? Une autre façon d'aborder cela serait d'utiliser Elysia cron qui a un certain nombre d'améliorations significatives au fonctionnement de cron mais deux qui pourraient être pertinentes pour votre cas d'utilisation sont:
Vous pouvez utiliser ce module pour avoir un meilleur contrôle sur la façon dont votre cron s'exécute pour aider à résoudre le problème de cache périmé. Plus précisément, vous pouvez ajouter un point d'ancrage à vos fonctions de reconstruction à cron, puis à l'aide d'Elysia cron, définissez ces opérations pour qu'elles s'exécutent immédiatement après l'opération d'effacement du cache.
Il semble également que vous ayez des problèmes avec l'exécution de cron, ce qui conduit à une recréation trop fréquente du cache. Si tel est le cas, vous pouvez définir l'opération de vidage du cache spécifique dans Elysia cron pour qu'elle s'exécute à un rythme différent du reste de vos opérations cron. 6 heures, etc.
la source
Pour ce faire, utilisez-le
hook_flush_caches
en combinaison avecregister_shutdown_function
. Exemple de code:L'utilisation
register_shutdown_function
signifie que notre fonction de reconstruction de cache sera appelée après l'effacement des caches. Nous abusonshook_flush_caches
d'une manière qui n'a jamais été destinée à être utilisée, mais cela devrait faire exactement ce dont vous avez besoin.la source
register_shutdown_function()
de Drupal et suis tombé sur drupal_register_shutdown_function () : "Wrapper pour register_shutdown_function () qui intercepte les exceptions levées pour éviter" Exception levée sans cadre de pile dans Inconnu " . I Je sais que cela me fait du bienabusing hook_flush_caches
si j'utilise uniquement les fonctions de base de Drupal pour le faire.Non, il n'y en a pas. Pas vraiment. Du moins pas dans 6 ou 7. En supposant 7:
Si vous regardez
drupal_flush_all_caches()
vous verrez qu'il invoquehook_flush_caches()
. Ce crochet est destiné à:Il serait tentant de simplement faire durer le hook de votre module et d'y écrire du code. Mais regardons à nouveau
drupal_flush_all_caches()
. La suppression réelle se produit comme ceci:Cela signifie que tous les crochets sont tirés avant que quoi que ce soit ne soit vraiment effacé. Il n'y a qu'une seule fonction appelée après la suppression réelle,
_system_update_bootstrap_status()
mais elle appelle seulementhook_boot
,hook_exit
,hook_watchdog
ethook_language_init
- crochets que vous ne voulez pas mettre en œuvre que pour fournir des fonctionnalités en fonction de claire-cache.la source
Grands traits ici:
Bien qu'il n'y ait pas de hook dans la pré-D8, vous pouvez écrire votre propre backend de base de données basé sur celui standard
DrupalDatabaseCache
, puis écrire une ou toutes sortes de logique dans votreclear()
fonction. Un coup d'œil rapide suggérerait que cela est assez simple en D7 (copiez simplement la classe dans votre nom personnalisé et modifiez-le, etc. en ajoutant unmodule_invoke_all()
comme approprié) et avec le module cache_backport fonctionnerait même en D6. Ensuite, pointez tous les bacs de cache que vous souhaitez imaginer sur clair et vous devriez être sur votre chemin.la source
Si vous regardez la source de
drupal_flush_all_caches()
etclear_cache_all()
, vous verrez qu'aucun hook n'est invoqué après la suppression, ce qui est un joli bug.Il est très difficile de garantir qu'un utilisateur n'aura jamais à attendre la création de certaines entrées de cache, j'essaie donc d'éviter autant que possible la suppression complète du cache.
Une méthode qui aide vraiment est de modifier la page de performances pour câbler un gestionnaire de soumission qui efface simplement les caches orientés vers l'avant et ne touche pas les menus, le registre et les caches de base similaires. J'ai obtenu de bons résultats avec cela, car la reconstruction du menu et du registre prend environ la moitié du temps pour une reconstruction complète du cache.
L'autre chose que j'ai un script drush qui fait un
drupal_http_request()
sur toutes mes URL (pas seulement les plus importantes) pour que tout soit mis en cache. La manière de procéder varie selon le site. Parfois, je peux simplement EFQ les nœuds publiés et créer des URL de cette façon. D'autres fois, vous pouvez interroger les tables de sitemap XML pour obtenir votre URL. J'appelle ensuite cela depuis mon système cron aussi souvent que nécessaire.la source
Quelques options:
https://www.drupal.org/project/cache_graceful pourrait être exactement ce que vous voulez.
https://www.drupal.org/project/apdqc a 2 crochets qui se déclenchent sur un effacement de cache vous permettant de modifier l'effacement
drupal_alter('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);
et après vous avoir permis de réagir à l'effacementmodule_invoke_all('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);
. Faites fonctionner APDQC correctement et définissez-le$conf['apdqc_call_hook_on_clear'] = TRUE;
dans votre fichier settings.php, puis les hooks doivent être appelés chaque fois qu'un effacement du cache est effectué.la source
Cela peut ne pas convenir à tout le monde et peut ne pas être assez rapide pour l'OP - car il n'est déclenché qu'à l'initialisation de la page suivante. Cependant, cela m'a aidé à déclencher du code juste après un "cache effacer tout" qui n'était pas sensible au temps.
Si vous avez un bac spécifique que vous devez cibler, ce qui précède peut être modifié pour le prendre en charge, tant que le bac entier est vidé au moment où votre cache est vide.
hook_init
n'est exécuté que pour les pages non mises en cache. Bien qu'une suppression complète du cache ne signifie pas de pages mises en cache, cela ne devrait pas poser de problème. Cependant, les systèmes de mise en cache externes comme Varnish entraveront ce déclenchement, et signifieront que cela ne se produira que lorsque la prochaine demande appropriée reviendra à Drupal.la source
J'avais un besoin similaire, où un client voulait vider à la fois les caches Drupal et Varnish lorsqu'il appuyait sur le bouton "Vider tous les caches". J'ai détourné cet élément de menu pour le faire.
Cela n'atteindra aucun effacement du cache sur cron ou ailleurs - juste sur le lien du menu.
la source
Vous voudrez peut-être essayer https://www.drupal.org/project/recacher - il utilise le module d'expiration du cache pour détecter les pages expirées, puis re-cache uniquement ces pages en utilisant l'excellent HTTPRL.
la source