Иногда требуется периодически выполнять скрипт, время работы которого не укладывается в рамки серверных ограничений max_execution_time. Например, автоматический импорт больших списков или, как в моем примере, автоматический ресайз картинок инфоблока. В таких случаях требуется использовать пошаговый алгоритм.
Вот мой велосипед:
В данном примере скрипт раз в сутки проверяет наличие новых картинок и ресайзит их, но скрипт можно легко адаптировать и под другие задачи. Этот код можете использовать, если вы, так же как и я, любите использовать функцию ResizeImageGet для уменьшения картинок( http://dev.1c-bitrix.ru/api_help/main...ageget.php ).
Файл ImagesCronResize.php
<?
/*
*
* Скрипт автоматически кэширует все картинки в инфоблоке для ускорения загрузки страниц каталога
*
* */
class ImagesCronResize {
const MAX_EXECUTION_TIME = 40;
const AGENT_TIME_INTERVAL = 5; //минут
/*
* Агент ресайзит все превьюшки в инфоблоке под нужные размеры
*/
public static function resizeAgent($iLastId=0)
{
$startAgentTimestamp = time();
CModule::IncludeModule("iblock");
$arSelect = Array("ID", "NAME", "PREVIEW_PICTURE");
$arFilter = Array("IBLOCK_ID" => CATALOG_IBLOCK_ID, "ACTIVE" => "Y",">ID" => $iLastId );
$res = CIBlockElement::GetList(Array("ID"=>"ASC"), $arFilter, false, false, $arSelect);
while ($ob = $res->GetNextElement()) {
$arFields = $ob->GetFields();
if ($arFields['PREVIEW_PICTURE']>0) {
CFile::ResizeImageGet( $arFields['PREVIEW_PICTURE'], array('width'=>SMALL_PREVIEW_WIDTH, 'height'=>SMALL_PREVIEW_HEIGHT), BX_RESIZE_IMAGE_PROPORTIONAL, true); //BX_RESIZE_IMAGE_EXACT
CFile::ResizeImageGet( $arFields['PREVIEW_PICTURE'], array('width'=>BIG_PREVIEW_WIDTH, 'height'=>BIG_PREVIEW_HEIGHT), BX_RESIZE_IMAGE_PROPORTIONAL, true);
}
if ((time()-$startAgentTimestamp)>self::MAX_EXECUTION_TIME){
//Добавляем новый агент через 5 минут
self::addOneMoreStepAgent($arFields['ID']);
return false;
break;
}
}
return get_called_class()."::resizeAgent();";
}
public static function addAgent()
{
CAgent::AddAgent(
get_called_class()."::resizeAgent();", // имя функции
"", // идентификатор модуля
"N", // агент не критичен к кол-ву запусков
86400, // интервал запуска - 1 сутки
date("d.m.Y 05:00:00",strtotime("+1 day")),// дата первой проверки на запуск
"Y", // агент активен
date("d.m.Y 05:00:00",strtotime("+1 day")),// дата первого запуска
30);
}
protected function addOneMoreStepAgent($id)
{
CAgent::AddAgent(
get_called_class()."::resizeAgent(".intval($id).");", // имя функции
"", // идентификатор модуля
"N", // агент не критичен к кол-ву запусков
86400, // интервал запуска - 1 сутки
date("d.m.Y H:i:s",strtotime("+".self::AGENT_TIME_INTERVAL." minute")),// дата первой проверки на запуск
"Y", // агент активен
date("d.m.Y H:i:s",strtotime("+".self::AGENT_TIME_INTERVAL." minute")),// дата первого запуска
30);
}
}
?>
Лучше будет, если агенты будут работать на cron'e http://dev.1c-bitrix.ru/community/web...blog/2755/ Надеюсь кому-нибудь пригодится. Может кто посоветует, как улучшить алгортитм и расскажет о своих велосипедах.)
Вербовенко Федор, а) есть способы мониторить подвисшие скрипты б) вот как раз скрипты импорта, которые работают 2 часа нужно делать по крону, и этому процессу корректно выставлять пределы жрания памяти/процессора, чтобы они не мешали веб-серверу и другим процессам.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».