Задача
Реализовать массовое обновление всех постов на сайте. С рекурсивной обработкой и прослушкой состояния через 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″ /]
Если будут вопросы, задавайте.
Ну у меня больше вопросов чем ответов.
Почему , просто не сделать рекурсивный вызов например ,я ещё как то могу представить (вобще трудно придумать где это hearbit применить, даже если специально искать) , но зачем временные значения в транзишенах хранить , они разве они должны через время уничтожаться, что то не понял с ходу ?
И зачем там wp_ajax_nopriv_bpus_start, разве оно не только для авторизованых юзеров в админке ?
1. а что такое просто рекурсивный вызов? функции самой себя? Это будет означать что скрипт будет работать более 1 минуты и в какой то момент сервер его пристрелит. При больших объемах это приводит к ошибкам. И данные не до конца обрабатываются.
2. а где хранить временные значения кроме как не в транзитах? транзиты для этого и придуманы. Если их хранить в опциях, то они там и остаются. А транзиты через какое то время стираются и не засоряют базу мусором. Если данные временные, то логично что они нужны лишь на время обработки и нет смысла их хранить. Да, они должны через какое то время удалиться.
3. wp_ajax_nopriv нужен потому что если функция сама себя вызывает через урл, то это выглядит как некий веб сервер “А” вызвал другой веб сервер “Б”. И если клиент авторизован, то веб сервер “А” – нет. И если сделать лишь для авторизованных, то вторая итерация просто не запустится. АЯКС вернут ошибку.
Да nopriv нужен , в рекурсивно я имелвиду как в regenerate thumbnails например ,руководство на фронте не в php конечно же
не представляю как это сделать без зависимости от клиента.
можно чтобы на клиенте АЯКС периодически стартовал новый цикл, но когда клиент закроет браузер то отработка прервется.
А если делать выхов скрипта сами себя на стороне сервера, то на клиенте все равно надо писать AJAX скрипт для запроса состояния. И это по сложности выше чем Hearbeat API. Потому просто выбрано самое простое решение.