Подскажите как можно разделить выполнение кастомного макроса или разбить его. Постоянно таймаут.
Макрос по выборки "new selector('pages');" и дальнейшей обработки страниц участвующей в этой выборке.
В результате под обработку попадает в среднем около 9-11 тыс. объектов.
В обработки идет простой перебор, с сохранение данных, пример:
$pages = new selector('pages');
$pages->types('hierarchy-type')->name('catalog', 'object');
foreach($pages as $page) {
$page->setValue("fieldname", $newValue);
$page->commit();
}
Соответвенно обработать такой объем не получается, постоянно таймаут.
Запускается не по крону, а по требованию, в момент отправки POST запроса с другого приложения.
Подскажите как правильно сделать, куда смотреть?
Наверно надо поподробнее описать. Не правильно вопрос изначально задал.
Из сторонего приложения в систему загружался файлик CSV, с id объектами и данными для из изменения. В файлики около 9-11 тыс. строк.
Изначально было так. На html страничке, была форма загрузки файла и он обработался через JS. Т.е. человек получал файл заходил на страницу и загружал его, после загрузки ajax ом, отправлялись данные на url (на кастомный скрипт) с параметрами ограничения выборки. А в самом кастомном скрипте был простой код который перебирал эти строки. Отправляли с ограничением выборки по 50 шт. И всё прекрасно работало.
// Приблизительно вот так:
$actionFile = file_get_contents($fileImport);
$lines = explode("\n", $actionFile);
$i = 0;
$step = 50;
$offset_next = $offset + $step;
foreach ($lines as $line) {
if($i >= $offset and $i <= $offset_next) {
$pages = new selector('pages');
$pages->types('hierarchy-type')->name('catalog', 'object');
$pages->where('is_active')->equals(array(0,1));
$pages->where('id')->equals(...);
$result = $pages->result();
$total_findpage = $pages->length();
..... сама обработка .....
}
$i++;
}
Сейчас задача изменилась, и файл для импорта ложится на сервер автоматом, по расписанию. И теперь надо по расписанию (CRON) вызывать его обработку. Как теперь сделать ограничение по выборке - непонятно. Целиком, весь этот файл при запуске через CRON не обрабатывается. Я так понимаю что в расписание я же не могу поставить файл в котором точно так же будет при помощи JS обрабатываться с ограничением выборки.
Вот в этом и стоит проблема. Если вообще не правильный подход - подскажите, направьте.
Сейчас задача изменилась, и файл для импорта ложится на сервер автоматом, по расписанию. И теперь надо по расписанию (CRON) вызывать его обработку. Как теперь сделать ограничение по выборке - непонятно. Целиком, весь этот файл при запуске через CRON не обрабатывается.
Очень даже обрабатывается. Вам нужно разбить скрипт на два независимых файла, например, cron1.php и cron2.php.
В первом вы получаете выборку и в цикле ее перебираете. Внутри цикла вы вызываете cron2.php, в который передаете нужные параметры, например, id элемента, и уже в этом файле идет обработка выбранного элемента.
ваш изначальный пример выглядеть будет примерно так:
#!/usr/local/bin/php
<?php
## Подключаем систему ##
//говорим ЮМИ, что работаем из консоли
define("UMICMS_CLI_MODE", "1");
//Определяем _SERVER-переменные, не существующие в CLI
// имитируем для ЮМИ работу по http
$_SERVER['DOCUMENT_ROOT'] = dirname(dirname(__FILE__));
$_SERVER['SERVER_ADDR'] = '127.0.0.1';// UMI.CMS licensing
$_SERVER['HTTP_HOST'] = 'site.ru';
ini_set('include_path', $_SERVER['DOCUMENT_ROOT'].'/');
$_REQUEST['path'] = "/admin/";
//переходим скриптом в корень сайта, чтобы иметь возможность
//указывать пути от корня сайта, а не сервера
chdir($_SERVER['DOCUMENT_ROOT'].'/');
include $_SERVER['DOCUMENT_ROOT']."/config.php"; //ПРИМЕР ДЛЯ ВЕРСИИ 2.7 !!!!!
## Ваш скрипт ##
$pages = new selector('pages');
$pages->types('hierarchy-type')->name('catalog', 'object');
foreach($pages as $page) {
shell_exec("./cron2.php " . $page->id);
}
?>
#!/usr/local/bin/php
<?php
## Подключаем систему ##
// Все то же, что в первом скрипте
## Ваш скрипт ##
$id = (int) $argv[1];
$page = umiHierarchy::getInstance()->getElement($id);
$page->setValue("fieldname", $newValue);
$page->commit();
?>
Для сервера при вызове shell_exec создается новый процесс, ресурсы и время выполнения которого не суммируются с родительским. Поэтому даже на виртуальном хостинге можно постепенно, очень неспешно, перебрать все элементы.
Я же, для ускорения процесса, добавлял в первый скрипт еще один цикл, чтобы передавать не один элемент, а несколько.