Ich habe eine Aufgabe, die ungefähr 45 Minuten dauert und jeden Tag ausgeführt werden muss (Synchronisierung von Benutzern mit mehreren externen Datenbanken usw.).
Um die Arbeit zu erledigen, habe ich eine Cron-Warteschlange hook_cron_queue_info()
wie folgt eingerichtet:
function mymodule_cron_queue_info() {
$queues = array();
$queues['update_users_queue'] = array(
'worker callback' => '_mymodule_process_user_queue_item',
'time' => 120,
);
return $queues;
}
Ich fülle die Warteschlange mit dieser Funktion:
function mymodule_queue_all_users_for_synching() {
//...query for users...
$queue = DrupalQueue::get('update_users_queue');
foreach($users as $user) {
$queue->createItem($user);
}
}
Die Funktion zum Füllen der Warteschlange wird als Cron-Task aufgerufen. Ich benutze Elysia Cron , daher ist meine Implementierung von hook_cronapi()
:
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;
}
Die Worker-Funktion für jedes Warteschlangenelement, das in definiert mymodule_cron_queue_info
ist, sieht folgendermaßen aus:
function _mymodule_process_user_queue_item($item) {
//...synchronize user ($item)...
}
Meine Frage ist, wann wird cron tatsächlich mit der Bearbeitung der Warteschlange beginnen?
Angenommen, ich fülle die Warteschlange jeden Tag um 3 Uhr morgens und möchte sie alle 30 Minuten für 120 Sekunden verarbeiten, bis sie fertig ist. Muss ich eine weitere Cron-Aufgabe erstellen?
Antworten:
Wenn Drupal Cron-Tasks ausführt, werden automatisch alle aus Modulen definierten Cron-Warteschlangen verarbeitet
drupal_cron_run()
. Es werden zunächsthook_cron()
Implementierungen aufgerufen und anschließend die Cron-Warteschlangen geleert.Inmplementing
hook_cronapi()
können Sie einen Eintrag für eine andere Funktion hinzufügen, die die Cron-Warteschlange Ihres Moduls verwaltet.Die Alternative besteht darin, dass Drupal die Cron-Warteschlange für Sie verwaltet. Dies geschieht jedoch, wenn Drupal-Cron-Tasks ausgeführt werden. Wenn Sie die Cron-Warteschlange Ihres Moduls häufiger leeren möchten, können Sie nur eine neue Cron-Aufgabe hinzufügen, die vom Elysia Cron-Modul verwaltet wird.
Das Elysia Cron-Modul verwaltet die Cron-Warteschlangen in
elysia_cron_run()
; Diese Funktion wird vonelysia_cron_cron()
(einer Implementierung vonhook_cron()
),drush_elysia_cron_run_wrapper()
(einem Drush-Befehlsrückruf) und von seiner eigenen cron.php aufgerufen . Wenn Sie den Anweisungen in der Datei INSTALL.txt gefolgt sind (insbesondere in "SCHRITT B: SYSTEM CRONTAB ÄNDERN (OPTIONAL)") und einen Aufruf von http://example.com/cron.php durch http: // example ersetzt haben .com / sites / all / modules / elysia_cron / cron.php sollte die Elysia cron - Modul bereits sein , die cron - Warteschlangen Handhabung. Der von mir vorgeschlagene Code kann verwendet werden, um die Verarbeitung der von Ihrem Modul verwendeten Cron-Warteschlangen zu beschleunigen, wenn dies tatsächlich erforderlich ist.quelle
cron.php
? Wenn das der Fall ist, passiert das jede Minute (siehe meinen ersten Kommentar zu @ Davids Antwort).elysia_cron_run
bei der die cron-Warteschlangen jedes Mal automatisch verarbeitet werden, wenn Elysias cron.php angefordert wird.Die Warteschlange wird zum festgelegten Zeitpunkt über den Elysia-Cronapi-Hook gefüllt.
Die Warteschlange wird jedoch immer dann verarbeitet, wenn der Standard-Drupal-Cron-Lauf stattfindet.
Sehen Sie sich dieses Worker-Callback-Verarbeitungs-Snippet am Ende des Kerns an: drupal_cron_run
quelle
cron.php
Skript jede Minute ausgelöst wird , wodurch Elysia die Task-Zeiten mit einer minutengenauen Auflösung steuern kann. Tatsächlich läuft aber keine Aufgabe jede Minute - was hat mich zu der Annahme veranlasst, dass ich eine Aufgabe erstellen musste, um speziell an Warteschlangen zu arbeiten?drupal_cron_run
aufgerufen wird, wird Ihr Cron Queue Worker Callback verarbeitet.drupal_cron_run
jedoch nicht vom Elysia-cron.php
Skript aufgerufen (wenn Elysia aktiviert ist);elysia_cron_run
wird stattdessen verwendet.hook_cron_queue_info
Elysia cron anscheinend nicht verwenden , es sei denn, Sie geben Ihren eigenen Worker-Rückruf an, wie imdrupal_cron_run
obigen Kernfunktionsausschnitt beschrieben.elysia_cron_run
nicht nennendrupal_cron_run
, aber es tut Anrufmodule_invoke_all('cron_queue_info')
und hat einige fancy-Hose Multi-Channel - Handling , das macht meine Ohren rauchen kommen.Wie oben erwähnt, werden Ihre Warteschlangen bei der Verwendung von Elysia Cron nicht verarbeitet.
Sie (und Drupal) haben keinen Zugriff auf Warteschlangen, die andernfalls auf Drupal_run_cron ausgeführt würden
Die Problemumgehung besteht darin, eine benutzerdefinierte Cron-Aufgabe zu erstellen (die für elysia cron sichtbar ist), um entweder alle oder eine gewünschte Warteschlange zu verarbeiten und die Verarbeitung der Warteschlange dort aufzurufen. dh:
Jetzt kann die Verarbeitung von Warteschlangen von ElysiaCron gesteuert werden
quelle
Ich verwende Elysia nicht, aber meine Lösung war schon immer so:
Es wird nur ein Element für jeden Cron-Lauf verarbeitet. Vielleicht möchten Sie das ändern.
quelle
Ich habe auch versucht, mich damit abzufinden, da ich zusammen mit Elysia cron zum ersten Mal die Queue-API verwende. Bei näherer Betrachtung können Sie sehen, dass Elysia cron beim Aufruf der Funktion elysia_cron_run Queue Items ausführt . Sehen Sie sich diesen Ausschnitt aus Zeile 1044 in der Datei elysia_cron.module an :
Dies hat mir bei der Verwendung von Elysia cron geholfen, die Warteschlangenverarbeitung zu entmystifizieren.
quelle