Довольный толстый кот

Запуск импорта WP All Import по cron из командной строки

Плагин WP All Import — это очень мощный инструмент импорта в WordPress, который может использоваться в самых разных сценариях, например, для импорта или синхронизации товарного каталога WooCommerce с данными, полученными из 1С или из выгрузки поставщика товаров. Однако, этому плагину присущ ряд особенностей:

  1. WP All Import не использует WP Cron в полной мере, а требует явного вызова wp-cron.php со своими параметрами. Фактически он требует двух вызовов: т.н. триггер, запускающий импорт, и шаг итерации импорта (тик), в котором обрабатывается очередная порция данных. Разработчики рекомендуют для второго вызова (тика) ставить время повторения около 2 минут, но на практике этого времени может не хватить. Увеличение же этого времени приводит к увеличению пауз в импорте и росту общего времени импорта. В результате оно реально может вырасти до нескольких часов на больших объемах данных.
  2. Хоть WP All Import и умеет скачивать файлы у поставщика, но WAI работает только с кодировкой UTF-8, а большинство российских поставщиков дают те же CSV файлы в Windows-1251 (привет 1С-программистам!). Загрузки все равно требуют дополнительной обработки.

Всё это явно просится быть перенесённым на уровень серверного ПО, а не выполнять его в админке WP или вызовами по cron wget. Но, к сожалению, WAI не умеет работать ни с WP-CLI, ни в командной строке. И я озадачился поиском решения.

Решение было найдено. Вот оно:

Идея,  реализованная Rolandow, заключается в прямом вызове PHP CLI сначала триггера, а потом последовательном вызове тиков WAI с секундной задержкой до тех пор, пока очередной тик не скажет, что импортировать больше нечего. Плюсы очевидны:

  • Все работает в CLI, поэтому нет никаких лимитов на время исполнения.
  • Веб-сервер не грузится.
  • Тики итераций идут почти впритык друг к другу и выполняются ровно столько, сколько они выполняются.
  • Всё это великолепно вызывается через cron.

Простой эксперимент показал, что тот импорт, который у нас занимал более 25 минут, выполнился за 10 мин.

Итак, вот наше решение, немного упрощенное и переделанное из исходного. Важно в скрипте задать следующие переменные:

  • JOB_ID — номер задания WP All Import (берется в админке WP All Import)
  • KEY — ключ для запуска (берется там же)
  • LOGFILE — имя и расположение файла лога
  • CURLOG — имя временного лога (он жизненно необходим для работы!)
  • ROOT_DIR — путь к руту сайта

Сейчас значения стоят так, как мы обычно делаем на наших серверах, но вы должны их явно определить.

#!/bin/bash

SITE="your-site.ru"
JOB_ID=999
KEY="Your-Key"
LOGFILE=/var/www/$SITE/logs/wp-all-import.log
CURLOG=/var/www/$SITE/logs/wp-all-import-$JOB_ID.tmp
ROOT_DIR=/var/www/$SITE/www
DONE=0

function log {
  echo "$(date): $*" >>$LOGFILE
}

echo "WP All Import:" $SITE " job id:" $JOB_ID
cd $ROOT_DIR
log "Start import for job id $JOB_ID"

php -e -r 'parse_str("import_key='$KEY'&import_id='$JOB_ID'&action=trigger", $_GET); include "wp-cron.php";' >>$LOGFILE 2>&1
sleep 1

while [ $DONE -eq 0 ]
do
  php -e -r 'parse_str("import_key='$KEY'&import_id='$JOB_ID'&action=processing", $_GET); include "wp-cron.php";' >$CURLOG 2>&1
  cat $CURLOG >>$LOGFILE
  DONE=$(grep 'is not triggered' $CURLOG | wc -l)
  sleep 1
done
rm $CURLOG

log "End of import for jobId" $JOB_ID
log ""
log ""

Вот, собственно, и все. Комментарии и вопросы приветствуются.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Back To Top