dikey58
@dikey58
Самоучка - web-разработчик

Агенты на 1С-Битрикс. Как лучше выполнять потенциально тяжелые скрипты?

Есть задача, в которой на сайте должны заполняться типы цен для товара. При полной выгрузке из 1с, получается номенклатура в 14тыс. позиций, для которых требуется заполнение типов цен. В свойствах инфоблока каталога добавлена галочка для товара "Обновить типы цен". Реализован скрипт, который ищет элементы, у которых стоит галка "Обновить типы цен", и заполняет у них типы цен. Запуск скрипта добавлен в агенты с запуском через заданный интервал. Если делать за раз все, то скрипт может быть очень долгим, поэтому поставлено ограничение на 600 элементов с галочкой "Обновить типы цен" за раз и интервал установлен в 600 (на это требовалось скрипту в среднем две минуты). Как цены были установлены, у элемента снимается галочка и обновляется фасетный индекс
\Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex($iBlockID, $productID);

То есть после полной выгрузки, какое-то время будет сайт подтормаживать, но зависать не должен. А когда все цены обновлены, скрипту требуются доли секунды, чтобы убедиться, что ничего к обновлению нет.
Но по непонятным причинам в таблице агентов, наблюдалось, что агент перестал обновлять время следующего запуска. При ручной попытке запуска скрипта из командной строки PHP в админке битрикса, система выдала ошибку "Deadlock found when trying to get lock; try restarting transaction", на строчке обновления индекса. Но так было только один раз и пока больше не повторялось.
Как лучше реализовать такой скрипт?
  • Вопрос задан
  • 516 просмотров
Пригласить эксперта
Ответы на вопрос 4
smilingcheater
@smilingcheater
Вы в курсе, что агенты на проде рекомендуется запускать не на хитах, а по крону?
https://dev.1c-bitrix.ru/learning/course/?COURSE_I...
Ответ написан
sabramovskikh
@sabramovskikh
Тяжелые скрипты обычно вешаю прям на крон, без самого битрикса
Создаю файл
<code lang="php">
if (substr(php_sapi_name(), 0, 3) !== 'cli') {
    die();
}
define('NO_KEEP_STATISTIC', true);
define('NO_AGENT_CHECK', true);

if (empty($_SERVER['DOCUMENT_ROOT'])) {
    $_SERVER['DOCUMENT_ROOT'] = realpath(dirname(__FILE__) . '/../');
}

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

тут код который надо выполнить


require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');

</code>
Ответ написан
bziker
@bziker
linux sysadmin
Тяжелые, не зависящие от поведения пользователя скрипты лучше на крон, ночью (ну или когда активность минимальная и чтоб ни с чем не пересекалось), только не из пыхи, а из /etc/crontab
Ответ написан
Комментировать
dikey58
@dikey58 Автор вопроса
Самоучка - web-разработчик
В общем там сложная задача была. Надо было, чтобы после выгрузки по каталогу происходило обновление значений типов цен (заказчик отказывался слать значения типов цен с 1с). Заказчик почему-то поставил задачу, чтобы это происходило после выгрузки, видимо переживал, что выгрузку тормозить сильно будет. Таким образом надо было запускать на крон. Но чтобы можно было всегда включить или выключить админу сайта я решил делать через агенты и настроить их запуск на cron.
Но там был подводный камень: оказывается, что если скрипт агента, который выполняется дольше 10 минут, то он запускается еще раз. Таким образом у меня было несколько запущенных агентов одновременно, что увеличивало по времени выполнение агента в целом, но на результат не влияло.

В итоге я попробовал повесить обновление значений типов цен на событие обновления цены элемента каталога и как оказалось там всё быстро отрабатывает. Но там тоже был подводный камень: 1с при выгрузке устанавливая основную цену, стирает остальные значения типов цен после события обновления основного типа цены, которое затирало мне изменения мною установленных значений типов цен. Короче пришлось повесить проверку. А установка мною новых значений типов цен запускало то же самое событие. Короче пришлось попотеть, чтобы всё работало корректно и из админки и из обновления через 1с.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы