Cron + Drupal Queue - проблема с _cron_queue_info колбэками

Аватар пользователя oOLokiOo oOLokiOo 18 сентября 2012 в 17:17

Доброго времени суток.
Суть такова - нужно по крону распаковывать архивы, ставя задачи в очередь. Делаю вроде бы всё по мануалу, но как не крути, в mymodule_unzip_file ломиться не хочет...
Может кто сталкивался? Что я делаю не так?

Еесть у меня хук для Крона:

<?php
/**
 * Implements hook_cron().
 */
function mymodule_cron()
{
    
$items mymodule_get_info_db();

    if (

$items) {
        
$queue DrupalQueue::get('collections');
        
$queue->createQueue();
        foreach (
$items as $item) {
            
$queue->createItem($item);
        }
    }
}
?>

Есть:

<?php
/**
 * Implements hook_cron_queue_info().
 */
function mymodule_cron_queue_info()
{
    
$queue['collections'] = array(
        
'worker callback' => 'mymodule_unzip_file',
        
'time' => 60,
    );

    return 

$queue;
}
?>

Ну и есть:

<?php
/**
 * Collections queue callback.
 */
function mymodule_unzip_file($item)
{
 ...
}
?>

Комментарии

Аватар пользователя rimen rimen 19 сентября 2012 в 4:13

Проверьте, что задания в очередь вообще встают.
createItem() возвращает TRUE, если задание успешно добавлено в очередь. Ну и на край таблицу очередей в БД тоже проверьте.

Аватар пользователя oOLokiOo oOLokiOo 19 сентября 2012 в 10:08

Кеш я чищу, всё ок.

В очередь тоже похоже становиться. В таблицу "queue", при каждом запуске крона добавляется по две записи.
drush queue-list тоже показывает их (collections 2 SystemQueue).
Если сделать: drush queue-run collections, тогда оно идёт на колбэк указанный в mymodule_cron_queue_info и всё выполняется и очередь становиться пустой.
Это что, мне ещё второй Крон заюзать и в нём делать drush queue-run collections постоянно? Это же как-то не правильно имхо, нет?

Аватар пользователя rimen rimen 19 сентября 2012 в 10:49

Суть: Задачи становятся в очередь по крону. Задачи выполняются по крону. Второй крон не нужен. Если поглядите в api, в 7ке cron отрабатывает с прицелом на очереди. (в 6ке на backport Drupal Queue действительно приходилось выносить на отдельный запуск крона).

Аватар пользователя rimen rimen 19 сентября 2012 в 10:51

То есть крон должен вызываться достаточно часто (в зависимости от нужд). Например, Нужно паковать 10 файлов, критичное время - 1 час. за один проход крона пакуется 2 файла. Итого считаем ,как часто нужно пускать крон, чтобы удовлетворять нуждам

Аватар пользователя oOLokiOo oOLokiOo 19 сентября 2012 в 11:29

да, Крон у меня вызывается каждую минуту.
суть такова - если в базе появилась запись(и), он достаёт их и запихивает в очередь (имя файла), а в mymodule_cron_queue_info указан колбэк для распаковки этого файла - mymodule_unzip_file.
но на него никак не идёт. даже если нету новой записи в базе, он всё равно не хочет выполнять колбэк. а если есть новая запись, он её кидает на стек и всё. таким образом collections просто растёт.

Аватар пользователя rimen rimen 19 сентября 2012 в 12:21

"oOLokiOo" wrote:
Если сделать: drush queue-run collections, тогда оно идёт на колбэк указанный в mymodule_cron_queue_info и всё выполняется и очередь становиться пустой.

Судя по этому могу предположить только, что при обычном запуске cron не успевает дойти до обработки твоей очереди, хотя это весьма странно.

Попробуй через hook_cron_queue_info_alter() посмотреть список задач, которые встают по крону. Там же можно попробовать выставить свой qollections в начало, так твоя очередь должна пойти на обработку в 1-ой

Аватар пользователя oOLokiOo oOLokiOo 19 сентября 2012 в 15:39

"rimen" wrote:
Попробуй через hook_cron_queue_info_alter() посмотреть список задач, которые встают по крону. Там же можно попробовать выставить свой qollections в начало, так твоя очередь должна пойти на обработку в 1-ой

а можно немного подробней на этом моменте? я с друпалом не много знаком, а hook_cron_queue_info_alter не сильно документирован...

Аватар пользователя rimen rimen 19 сентября 2012 в 15:44
<?php
mymodule_cron_queue_info_alter
(&$queues){
  
// dpm($queues); //если devel есть
  
print_r($queues);
}
?>

Запустите крон вручную. посмотрите, какие вообще очереди у вас в есть ( и обрабатываются). можно сюда выложить список.

Ну и попробуйте свою очередь поставить в этом же хуке в начало массива - если все равно не исполнится, значит дело в чем-то ином.

Аватар пользователя oOLokiOo oOLokiOo 19 сентября 2012 в 16:11

"rimen" wrote:
Запустите крон вручную. посмотрите, какие вообще очереди у вас в есть ( и обрабатываются). можно сюда выложить список.

Есть там мои collections, и первые в очереди...

<?php
Array
(
    [
'collections'] => Array(
        
'worker callback' => 'mymodule_unzip_file',
        
'time' => 60,
    )
)
?>

Даже вот так попробовал:

<?php
function mymodule_cron_queue_info_alter(&$queues) {
    
$queues['collections']['time'] = 90;
    
print_r($queues);
}
?>

time стал 90.

Аватар пользователя oOLokiOo oOLokiOo 19 сентября 2012 в 17:56

кстати Крон у меня дёргает каждую минуту функцию - mymodule_cron() (см. 1ый пост)
тут-то всё же верно, да?

Аватар пользователя rimen rimen 20 сентября 2012 в 9:02

это нормально, hook_cron для этого и нужен. Если хотите управлять частотой запуска задач, смотрите модули типа Elysia Cron.

"rimen" wrote:
Кстати, поглядите watchdog - что там по cron есть ?

?

Аватар пользователя oOLokiOo oOLokiOo 20 сентября 2012 в 10:20

"rimen" wrote:
Кстати, поглядите watchdog - что там по cron есть ?

в смысле вот тут? admin/reports/dblog
про Крон вообще тишина. мистика какая-то...

я правильно понимаю процесс?
- при запуске Крона, идём в mymodule_cron()
- берём записи из базы с помощью mymodule_get_info_db()
- если есть записи то ставим их в очередь
- если записей нет, то что? DrupalQueue проверяет если что-то в очереди и выполняет это пройдя по указанным колбэкам в mymodule_cron_queue_info? а если нет ничего то ждёт последующего запуска по Крону и сначала по кругу?

Аватар пользователя rimen rimen 20 сентября 2012 в 10:25

cron выполняет hook_cron (у вас ставятся задания в очередь) а также выполняет задания из очереди (по возможности, пока время есть), если таковые имеются (получает инфу по всем очередям из hook_cron_queu_info и проходит по ним в цикле).
Подрбнее тут http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_c...

Аватар пользователя rimen rimen 20 сентября 2012 в 10:28

При ручном запуске cron белого экрана или ошибок нет?
Просто при успешном запуске крон в журанле идет запись об этом. Если посмотрите на код функции (выше ссылка) то запись в watchdog добавляется как раз перед обработкой очередей.
Если записи нет, проверьте, что крон в целом нормально отрабатывает.

Аватар пользователя oOLokiOo oOLokiOo 20 сентября 2012 в 10:57

"rimen" wrote:
При ручном запуске cron белого экрана или ошибок нет?

да нет, всё отлично проходит, пишет "Job executed", логирует "Dernier lancement", "Exec count" и т.д.
но в журнал ничего не пишет...

Аватар пользователя oOLokiOo oOLokiOo 20 сентября 2012 в 10:58

У меня стоит "Elysia Cron 7.x-2.1". Может там где-то в настройках можно включить логирование в журнал, но я не нашёл

Аватар пользователя rimen rimen 20 сентября 2012 в 11:23

Попробуй Elysia выключить.
Правда,сам использовал его в одном из последних проектов (синхронизация с 1С - импорт и обработка данных очередями) - проблем не было.

Аватар пользователя oOLokiOo oOLokiOo 20 сентября 2012 в 13:23

"rimen" wrote:
Попробуй Elysia выключить.
Правда,сам использовал его в одном из последних проектов (синхронизация с 1С - импорт и обработка данных очередями) - проблем не было.

так на нём весь текущий проект подвязан. или вы чем-то заменить его предлагаете?

я уже не знаю даже что и думать.. перепробовал - всё!

<?php
function mymodule_cron()
{
    
$queue DrupalQueue::get('collections');
    
$queue->createQueue();
    
watchdog('MyTest'"items count - ".$queue->numberOfItems());

    

$items gps_xml_import_get_info_db();

    if (

$items) {
        foreach (
$items as $item) {
            
$queue->createItem($item);
        }
    }
}

function 

mymodule_cron_queue_info()
{
    
$queue['collections'] = array(
        
'worker callback' => 'mymodule_unzip_file',
        
'time'            => 60,
    );

    

watchdog('MyTest'"here - mymodule_cron_queue_info");
    return 
$queue;
}

function 

mymodule_unzip_file()
{
    
watchdog('MyTest'"here - mymodule_unzip_file");
    return 
true;
}
?>

по запуску Крона, лог вижу в из mymodule_cron() и mymodule_cron_queue_info(), всё.
в mymodule_unzip_file() хоть убей, ни ногой...
при этом, drush queue-list показывает, что collections ростёт и по прежнему срабатывает на ура - drush queue-run collections

может кто ещё подскажет, куда посмотреть можно?

Аватар пользователя rimen rimen 20 сентября 2012 в 13:30

mymodule_unzip_file()
должен принимать аргумент - $item, который в очередь ставили

туплю, на работе в представленном контексте это никак не скажется

Аватар пользователя rimen rimen 20 сентября 2012 в 13:27

"oOLokiOo" wrote:
так на нём весь текущий проект подвязан. или вы чем-то заменить его предлагаете?

я предлагал отключить, чтобы запустить крон и проверить, как это сработает без елайзы