Скрипт длительного выполнения на агенте на cron

Задачку поставил заказчик:
Делать запросы со стороннего сайта о наличии товара и внесение этих данных в соответствующий элемент каталога.
Идентификатором (полем соответствия) служит артикул.
Первый скрипт для выполения через браузер заставил решить задачу таймаута, вышло примерно следующее:[spoiler]
set_time_limit(0);
$urlBegin = "http://www.ххх.хх/?partId=";
$getReqEnd = "&param...";
$count = ($_REQUEST['count']) ? $_REQUEST['count']: 0;
?>
<html>
<head>
</head>
<body>
<?
echo ' Start - '.$count.'<br>';
$flag=true;
$elemHave = "Ключевое слово";
// create array ID + Articles and load in SESSION
if ($count==0) {
CModule::IncludeModule('iblock');
$arSelect = Array("ID", "IBLOCK_ID", "PROPERTY_CML2_ARTICLE";
$res = CIBlockElement::GetList(array(), array("IBLOCK_ID" => ХХ, "SECTION_ID"=> ХХХ), false, false, $arSelect);
while ($ob = $res->GetNextElement()){
$arrFields = $ob->GetFields();
$arIdArticles[] = array('ID'=>$arrFields['ID'],'ARTICLE'=>$arrFields['PROPERTY_CML2_ARTICLE_VALUE']
}
}
else{
$arIdArticles = $_SESSION['arIdArticles'];
}
$_SESSION['arIdArticles'] = $arIdArticles;
$elemCount = count($arIdArticles);
Cmodule::IncludeModule('catalog');
while ($count<=$elemCount){
$getReq = strval($arIdArticles[$count]['ARTICLE']
$url = $urlBegin.$getReq.$getReqEnd;
$result = iconv('CP1251', 'UTF-8', file_get_contents($url));
$findRes = strstr($result, $elemHave);
$quant = ($findRes)? 1: 0;
CCatalogProduct::Update($arIdArticles[$count]['ID'], array('QUANTITY'=>$quant));
$arFieldStore = Array(
"PRODUCT_ID" => $arIdArticles[$count]['ID'],
"STORE_ID" => Х,
"AMOUNT" => $quant
);
CCatalogStoreProduct::UpdateFromForm($arFieldStore);
unset ($result);
if ((getmicrotime() - START_EXEC_TIME) > 90){
$flag=false;
file_put_contents("data.txt", 'Обработано - '.$count.' из '.$elemCount.' time start session - '.START_EXEC_TIME);
echo 'Обработано - '.$count.' из '.$elemCount.' time start session - '.START_EXEC_TIME;
break;
}
//     file_put_contents("data.txt", 'Обработано - '.$count);
$count++;
}
?>
</body>
</html>
<?
if (!$flag){ //LocalRedirect('/test/index.php?count='.$count);
?>
<script type="text/javascript">
setTimeout(function(){window.location='/test/index.php?count=<?=$count?>'},1500);
</script>
<?
}
else die();

убедившись, что цель достигнута, занялся переносом кода в init.php
в КМБ Битрикса сказано, что нельзя использовать в агентах $_SESSION т..е. логика перевызова скрипта, через определенное время не сработает.
Оказалось, что агент выполняющийся на кроне вовсе не обязан перезагружаться для корректной работы. Однако вылезли другие ограничения, которые заставили поплясать с бубном и понять, что же в конечнои итоге нужно сделать. Ограничения следующие: агент битрикса очень хочет выполниться в течении какого-то времени (интервал не определил), если он не завершил свое функционирование, то запускается его копия и тоже пытается выполнится, в результате чего можно получить 7-10 копий функции, которые делают одно и тоже, причем раннии копии теряются где-то в недрах сервера и есть подозрение, что не очищают память, конечно если вы об этом не позаботились. Таким образом агент мог выполнить максимум 28 000 циклов, после чего "терялся". Ну собственно КМБ Битрикса и об этом предупреждает: "не рекомендуется вешать на агенты ресурсоёмкие операции, для них существует фоновый запуск по cron'у." Поскольку доступа к крону у меня не было, принял решение "победить" агента. Итог:

function GetCSPresence(){
   
   if (!file_exists($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt")){
      $ptime = time()+432000;
      $headers= "MIME-Version: 1.0\r\n";
      $headers .= "Content-type: text/html; charset=UTF-8\r\n";
      $headers .= "From: SYSTEM";
      mail("info@site.ru", "Агент проверки стартовал", "Произведен запуск агента проверки наличия адрес - http://www.xxx.xx/", $headers);
      set_time_limit(0);
      $random_chars = array("0123456789");
      $randomNum = randString(8, $random_chars);
      file_put_contents($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt", 'Сессия - '.$randomNum);
      $urlBegin = "http://www.xxx.xx?partId=";
      $getReqEnd = "&param...";
      $count = 0;
      $elemHave = "Ключевое слово";
      CModule::IncludeModule('iblock');
      $arSelect = Array("ID", "IBLOCK_ID", "PROPERTY_CML2_ARTICLE");
      $res = CIBlockElement::GetList(array(), array("IBLOCK_ID" => X, "SECTION_ID"=> XX), false, false, $arSelect);
      while ($ob = $res->GetNextElement()){
         $arrFields = $ob->GetFields();
         $arIdArticles[] = array('ID'=>$arrFields['ID'],'ARTICLE'=>$arrFields['PROPERTY_CML2_ARTICLE_VALUE']);
      }
      $elemCount = count($arIdArticles);
      $inAvailable = 0;
      Cmodule::IncludeModule('catalog');
      foreach ($arIdArticles as $arVal){
   //   while ($count<=$elemCount){
         $getReq = strval($arVal['ARTICLE']);
         $url = $urlBegin.$getReq.$getReqEnd;
         $result = iconv('CP1251', 'UTF-8', file_get_contents($url));
         $findRes = strstr($result, $elemHave);
         $quant = ($findRes)? 1: 0;
         if($quant==1)$inAvailable++;
         CCatalogProduct::Update($arVal['ID'], array('QUANTITY'=>$quant));
         $arFieldStore = Array(
            "PRODUCT_ID" => $arVal['ID'],
            "STORE_ID" => 6,
            "AMOUNT" => $quant
         );
         CCatalogStoreProduct::UpdateFromForm($arFieldStore);
         unset ($result);
         if ($count%1000==0){
            file_put_contents($_SERVER['DOCUMENT_ROOT']."/logcs.txt", 'Сессия - '.$randomNum.' Обработано - '.$count.' в наличии - '.$inAvailable.PHP_EOL, FILE_APPEND);
            if (!file_exists($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt")) break;
         }
         $count++;
//         if ($randomNum) break;
      }
      file_put_contents($_SERVER['DOCUMENT_ROOT']."/logcs.txt", 'Сессия - '.$randomNum.' Обработано - '.$count.' из '.$elemCount.PHP_EOL, FILE_APPEND); 
      unlink($_SERVER['DOCUMENT_ROOT']."/bitrix/logcs.txt"); 
      mail("info@site.ru", "Агент проверки ЦС закончил", "Агент проверки наличия на ЦС адрес - http://www.xxx.xx/ закончил работу. Результат: обработано - ".$count.' из - '.$elemCount.' в наличии - '.$inAvailable.' следующй запуск - '.ConvertTimeStamp($ptime, "FULL"), $headers);
      unset ($arIdArticles);
//      return "GetCSPresence();";
   }
   if ($ptime)
      CAgent::AddAgent(
         "GetCSPresence();",
         "", // идентификатор модуля
         "N", // агент критичен к кол-ву запусков
         0, // интервал запуска
         "", // когда проверить первый запуск? (сейчас)
         "Y", // агент активен
         ConvertTimeStamp($ptime, "FULL") // начиная с какой даты проверять?
      );
}
 
Этот скрпт работает 28 часов