Пример массовой обработки постов в WordPress с прослушкой через Hearbeat API

Задача

Реализовать массовое обновление всех постов на сайте. С рекурсивной обработкой и прослушкой состояния через Hearbeat API.

Решаемые проблемы

Ошибка сервера по таймауту

Если данных много, в нашем случае постов около 50 000 штук. То попытка обработать их за один цикл – вешает сервер на глухо.

Нужно чтобы функция обрабатывала порциями весь массив и периодически сама себя перезагружала.

Решено через AJAX-механизм. По завершению обработки порции, функция сама себя вызывает через WP AJAX, с указанием новой порции через параметр $offset.

Прослушка через Hearbeat API

Встречал решения, где запуск новых порций требовал открытия клиентского окна. Это странно и хрупко.

Потому тут скрипт сам по себе работает на сервере. Сохраняя свои статусы в транзитном кеше WP (Transite Cache API).

А клиент если страниа открыта, прослушивает данные и выводит на страницу пользователя через WP Hearbeat API.

Реализация

Код тут https://github.com/systemo-biz/bulk-post-updater

Там все достаточно просто.

Вывод информации идет каждые 15 секунд на соответствующей странице в разделе инструментов:

[img attachment=”8430″ align=”alignnone” size=”large” alt=”Обновление всех постов ‹ CasePress — WordPress 2015-12-11 20-14-46″ /]

Если будут вопросы, задавайте.

комментария 4

  1. Ну у меня больше вопросов чем ответов.

    Почему , просто не сделать рекурсивный вызов например ,я ещё как то могу представить (вобще трудно придумать где это hearbit применить, даже если специально искать) , но зачем временные значения в транзишенах хранить , они разве они должны через время уничтожаться, что то не понял с ходу ?

    И зачем там wp_ajax_nopriv_bpus_start, разве оно не только для авторизованых юзеров в админке ?

    • 1. а что такое просто рекурсивный вызов? функции самой себя? Это будет означать что скрипт будет работать более 1 минуты и в какой то момент сервер его пристрелит. При больших объемах это приводит к ошибкам. И данные не до конца обрабатываются.
      2. а где хранить временные значения кроме как не в транзитах? транзиты для этого и придуманы. Если их хранить в опциях, то они там и остаются. А транзиты через какое то время стираются и не засоряют базу мусором. Если данные временные, то логично что они нужны лишь на время обработки и нет смысла их хранить. Да, они должны через какое то время удалиться.
      3. wp_ajax_nopriv нужен потому что если функция сама себя вызывает через урл, то это выглядит как некий веб сервер “А” вызвал другой веб сервер “Б”. И если клиент авторизован, то веб сервер “А” – нет. И если сделать лишь для авторизованных, то вторая итерация просто не запустится. АЯКС вернут ошибку.

  2. Да nopriv нужен , в рекурсивно я имелвиду как в regenerate thumbnails например ,руководство на фронте не в php конечно же

    • не представляю как это сделать без зависимости от клиента.
      можно чтобы на клиенте АЯКС периодически стартовал новый цикл, но когда клиент закроет браузер то отработка прервется.

      А если делать выхов скрипта сами себя на стороне сервера, то на клиенте все равно надо писать AJAX скрипт для запроса состояния. И это по сложности выше чем Hearbeat API. Потому просто выбрано самое простое решение.

Ответить

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