[Решено] Cron + Queue + node_load = access denied

Главные вкладки

Аватар пользователя Sun-fire Sun-fire 25 октября 2011 в 18:51

Пишу модуль, который в процессе работы получает список недавно изменившихся нод, далее каждую ноду разбирает по филдам, и значение каждого филда складывает с свой CSV.

Поскольку количество нод большое (3-5К) используется queue api. При этом на один элемент очереди приходится один тип контента (примерно 300-500 нод на один элемент очереди).

За один запуск крон обрабатывает примерно 3/4 всех очередей, после этого редиректит на страницу запуска крона с сообщением о том, что доступ запрещен. При повторной авторизации и запуске крона нормально обрабатывает оставшиеся 1/4 очередей и нормально завершается уже без всяких проблем.

Сам по себе функционал выгрузки полностью работоспособен - проверял "ручным" запуском без использования крона - без проблем "кушает" порциями до 1.5К нод, и не давится.

В логах друпала чисто.

Опытным путем, комментируя строчки кода, обнаружил, что "узкое место" в данном случае это функция node_load(). Все аргументы, которые передаются в нее корректны.

В чем может заключаться проблема, и куда копать по отладке такого типа проблем?

Комментарии

Аватар пользователя Shok211 Shok211 25 октября 2011 в 19:31

Ограничение времени выполнения скрипта смотрели ? В настройках очееди какое время стоит ? НУ вобщем советую рыть в этом направлении.
node_load - загружает весь материал + все поля. запросов к бд получается невероятно большое кол-во.

Аватар пользователя Orion76 Orion76 25 октября 2011 в 20:00

"Shok211" wrote:
node_load - загружает весь материал + все поля. запросов к бд получается невероятно большое кол-во.

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

Нужный запрос, если есть необходимость, можно у views "срисовать"-))

Аватар пользователя Sun-fire Sun-fire 25 октября 2011 в 23:13

По времени выполнения - общее время выполнения очереди "на глаз" как минимум наполовину меньше установленного таймаут-лимита. Для очереди он установлен 30 секунд, и в пхп соответственно тоже настроен на 30 секунд.

О "тяжеловесности" node_load мне известно, поэтому я не использую эту функцию при организации импорта на сайт.

Пока попробую увеличить время исполнения очереди, по результатам отпишусь.

Аватар пользователя Orion76 Orion76 25 октября 2011 в 23:44

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

Если что, в этом вопросе мои познания больше теоретические.. могу и ошибаться... но логика блин..-))

Аватар пользователя Sun-fire Sun-fire 26 октября 2011 в 1:37

Пускаю первый раз (когда ошибку выдает) крон как раз вручную. Под рутовой учетной записью, так что с правами точно должно быть все нормально.

Аватар пользователя Orion76 Orion76 27 октября 2011 в 13:11

поковырял модуль Queue... тоже надо..
чет не понял... если запускать стандартно через его cron-скрипт:

<?php
function drupal_queue_cron_run() {
  
drupal_queue_include();

  

// Try to increase the maximum execution time if it is too low.
  
if (ini_get('max_execution_time') < 240 && !ini_get('safe_mode')) {
    
set_time_limit(240);
  }

  

// Grab the defined cron queues.
  
$queues module_invoke_all('cron_queue_info');
  
drupal_alter('cron_queue_info'$queues);

  

// Work off queues.
  
foreach ($queues as $queue_name => $info) {
    
$function $info['worker callback'];
    
$end time() + (isset($info['time']) ? $info['time'] : 15);
    
$queue DrupalQueue::get($queue_name);
/*
$queue->claimItem()
выдергивает из базы очередное задание очереди с полем expire=0
в поле expire вводиться time()+15
*/

    

while (time() < $end && ($item $queue->claimItem())) {
      
$function($item->data);

/*
  $queue->deleteItem($item);

задание удаляется ищ БД
*/

      

$queue->deleteItem($item);
    }
  }
}
?>

То завершение выполнения задания очереди - по таймауту... т.е. если задание не успело выполниться, при следующем запуске запуститься следующее задание...

может еще в этом что-то..

Следовательно, контроль результата выполнения задания надо реализовывать самому...

Аватар пользователя Sun-fire Sun-fire 27 октября 2011 в 18:45

Проблема решена. Методом танца с бубном. Если перед ручным запуском корона почистить кэш, все отрабатывает как и должно быть. Если не почистить - чревато аварийным логаутом. В чем заключается эта особенность - пока хз, нужно посмотреть код ядра, каким образом там устроена обработка очередей.