J'ai une tâche qui prend environ 45 minutes et qui doit être effectuée chaque jour (synchronisation des utilisateurs sur plusieurs bases de données externes, etc.).
Pour gérer le travail, j'ai configuré une file d'attente cron avec hook_cron_queue_info()
les éléments suivants:
function mymodule_cron_queue_info() {
$queues = array();
$queues['update_users_queue'] = array(
'worker callback' => '_mymodule_process_user_queue_item',
'time' => 120,
);
return $queues;
}
Je remplis la file d'attente en utilisant cette fonction:
function mymodule_queue_all_users_for_synching() {
//...query for users...
$queue = DrupalQueue::get('update_users_queue');
foreach($users as $user) {
$queue->createItem($user);
}
}
La fonction de remplissage de la file d'attente est appelée en tant que tâche périodique. J'utilise Elysia Cron , mon implémentation hook_cronapi()
est donc:
function mymodule_cronapi($op, $job = NULL) {
$items = array();
$items['queue_users_for_synch'] = array(
'description' => 'Queue all user accounts for synching.',
'rule' => '0 3 * * *', // Run this job every day at 3am.
'callback' => 'mymodule_queue_all_users_for_synching',
);
return $items;
}
La fonction worker pour chaque élément de la file d'attente, définie dans, mymodule_cron_queue_info
est la suivante:
function _mymodule_process_user_queue_item($item) {
//...synchronize user ($item)...
}
Ma question est la suivante: quand cron commencera-t-il réellement à traiter la file d'attente?
Supposons que je remplisse la file d'attente tous les jours à 3 heures du matin et que je veuille la traiter 120 secondes toutes les 30 minutes jusqu'à ce que ce soit terminé - dois-je créer une autre tâche cron?
Réponses:
Lorsque Drupal exécute des tâches périodiques, il gère automatiquement toutes les files d'attente définies à partir de modules, dans
drupal_cron_run()
; les premièreshook_cron()
implémentations sont appelées, puis les files d'attente cron sont vidées.En implémentation
hook_cronapi()
, vous pouvez ajouter une entrée pour une autre fonction gérant la file d’attente cron de votre module.L'alternative est de laisser Drupal gérer la file d'attente cron pour vous, mais cela se produit lorsque les tâches cron Drupal sont exécutées. Si vous souhaitez vider la file d'attente périodique de votre module plus souvent, vous pouvez uniquement ajouter une nouvelle tâche périodique gérée par le module Elysia Cron.
Le module Elysia Cron gère les files d'attente cron
elysia_cron_run()
; cette fonction est appelée depuiselysia_cron_cron()
(une implémentation dehook_cron()
),drush_elysia_cron_run_wrapper()
(un rappel de commande Drush) et depuis son propre cron.php . Si vous avez suivi les instructions du fichier INSTALL.txt (en particulier dans "ÉTAPE B: CHANGER LE CRONTAB DU SYSTÈME (FACULTATIF)"), et avez remplacé tout appel de http://example.com/cron.php par http: // exemple. .com / sites / all / modules / elysia_cron / cron.php , le module Elysia Cron devrait déjà gérer les files d’attente cron. Le code que j'ai suggéré pourrait être utilisé pour accélérer le traitement des files d'attente cron utilisées à partir de votre module, si cela était effectivement nécessaire.la source
cron.php
? Si c'est le cas, cela se produit toutes les minutes (voir mon premier commentaire sur la réponse de @ David).elysia_cron_run
avec des files d'attente cron traitées automatiquement à chaque demande du fichier cron.php d'Elysia.La file d'attente sera remplie via le crochet Elysia cronapi à l'heure définie.
Cependant, la file d'attente sera traitée à chaque exécution de l'exécution cron Drupal standard.
Voir l'extrait de traitement de rappel de ce travailleur à la fin du noyau: drupal_cron_run
la source
cron.php
script Elysia toutes les minutes , ce qui permet à Elysia de contrôler les temps de travail avec une résolution minute. Cependant, aucune tâche ne s'exécute réellement toutes les minutes - qu'est-ce qui m'a fait penser que je devais créer une tâche pour travailler spécifiquement sur les files d'attente?drupal_cron_run
appel est en cours, le rappel de votre opérateur de file d'attente à cron sera traité.drupal_cron_run
ne vous appelez pas à partir ducron.php
script Elysia (lorsque Elysia est activé);elysia_cron_run
est utilisé à la place.hook_cron_queue_info
Elysia cron, à moins que vous ne spécifiiez votre propre rappel de travailleur, conformément à l'drupal_cron_run
extrait de fonction principal ci-dessus.elysia_cron_run
ne remet pasdrupal_cron_run
, mais il fait appelmodule_invoke_all('cron_queue_info')
et fait quelques-pantalons fantaisie manipulation multi-canal qui fait la fumée sortir mes oreilles.Comme indiqué ci-dessus lors de l'utilisation d'Elysia Cron, vos files d'attente ne sont pas traitées.
vous (et drupal) n'avez pas accès aux files d'attente qui s'exécuteraient autrement sur drupal_run_cron
La solution consiste à créer une tâche périodique personnalisée (cette tâche sera visible par elysia cron) afin de traiter toutes les files d'attente ou une de celles que vous souhaitez et d'appeler le traitement de la file d'attente à cet emplacement. c'est à dire:
le traitement des files d'attente peut maintenant être contrôlé par ElysiaCron
la source
Je n'utilise pas Elysia, mais ma solution a toujours été la suivante:
Il ne gère qu'un seul élément, pour chaque exécution cron. Peut-être que vous voulez changer cela.
la source
J'ai également essayé de comprendre la situation en utilisant pour la première fois l'API Queue avec Elysia Cron. En y regardant de plus près, vous constaterez qu'Elysia cron exécute les éléments de la file d'attente lorsque la fonction elysia_cron_run est appelée. Voir cet extrait de la ligne 1044 dans le fichier elysia_cron.module :
Cela m'a aidé à démystifier le traitement de la file d'attente lors de l'utilisation d'Elysia cron.
la source