PHP SDK: Параллельность, журнал и прогресс
Ускоряйте независимые запросы небольшими пачками. Параллельность не отменяет RPS сайта и лимиты тарифа. Если источник разрешает один запрос в секунду, большая пачка не должна превращаться в десятки одновременных обращений.
Пример обработки списка карточек
В параметре product_urls передайте список URL, не больше восьми в этом примере. На каждой странице должны быть .sku и h1. Для большого каталога разбивайте список на пачки.
<?php
function run(\Sdk\Context $ctx): void
{
$urls = $ctx->param('product_urls', []);
if (!is_array($urls) || count($urls) === 0 || count($urls) > 8) {
$ctx->abort('Передайте от 1 до 8 адресов в product_urls');
}
$total = count($urls);
$ctx->progress(0, $total, 'Загружаем карточки');
$responses = $ctx->http()->pool($urls);
$done = 0;
foreach ($responses as $response) {
if (!$response->ok()) {
$ctx->abort('Ошибка карточки: HTTP ' . $response->status);
}
$dom = $response->dom();
$sku = $dom->text('.sku');
if ($sku === null || $sku === '') {
$ctx->abort('В карточке не найден артикул');
}
$ctx->emit(['sku' => $sku, 'name' => $dom->text('h1')], $sku);
$done++;
$ctx->progress($done, $total, 'Обрабатываем карточки');
$ctx->log('Карточка обработана', ['done' => $done, 'total' => $total]);
}
$ctx->flush();
$ctx->log('Все карточки переданы на сохранение');
}
pool принимает от 1 до 8 адресов и сохраняет порядок ответов. Одновременно выполняется не более двух HTTP-запросов, с учётом общих ограничений сайта. Браузерные действия имеют свои ограничения и не становятся параллельными автоматически.
Пользовательские этапы
$ctx->progress($done, $total, $label) показывает счётчик и название этапа. Название произвольное: «Ищем категории», «Читаем остатки», «Проверяем товары». Если total неизвестен, передайте null. Не придумывайте процент наугад.
Можно передать явный процент четвёртым аргументом: $ctx->progress(15, 30, 'Карточки', 65.0). Это полезно, если карточки занимают только часть общего алгоритма. Продумайте вес каждого этапа, чтобы общий процент не прыгал назад.
100% пользовательского этапа означает завершение объявленной вами работы. Прогон может ещё сохранять данные и готовить результат. Окончательное завершение определяйте по статусу прогона.
Что писать в журнал
Используйте $ctx->log('Сообщение', ['поле' => 'значение'], 'info'). Для пропусков и отклонений подходит warning. Указывайте категорию, номер страницы, количество карточек и причину остановки. Не пишите в лог целые ответы сайта, пароли или тысячи одинаковых строк.
Состояние, которое нужно восстановить после возобновления, храните через $ctx->state()->get() и set(). Отмечайте страницу обработанной только после передачи её записей; при повторном чтении используйте стабильные ключи. Не считайте локальную переменную сохранённым курсором.
Ограничения среды
Внутри сценария нет прямого доступа к файловой системе, shell и произвольной сети. Используйте методы SDK. Для файлов во внешнем S3 предназначен $ctx->storage('code'), где code соответствует разрешённому подключению сайта. Доступные функции и методы показываются в подсказках редактора и проверяются при сохранении.