Вопрос или проблема
Я создал пользовательский плагин для WordPress, в котором я использую wp ajax. В конструкторе класса у меня есть действие (admin_footer), чтобы использовать wp_enqueue_script и wp_localize_script в соответствии с инструкциями WordPress.
Таким образом, поток выглядит как php -> js -> и снова php.
Почему я это делаю? Чтобы избежать ошибки предела памяти. Здесь говорится что-то приятное: “Вышеописанное решение обходит ограничения PHP, разбивая одну большую задачу на несколько меньших”.
Все работает прекрасно на бэкенде!
Мой вопрос заключается в том, как я могу управлять этим процессом, чтобы он работал с wp-cron? Возможен ли для wp-cron запуск js?
Я попробовал wp_schedule_event с моим пользовательским хуком без успеха (js никогда не работает).
Есть идеи?
С уважением
Прежде всего, подумайте о том, чтобы использовать новый REST API вместо Admin-AJAX в вашей среде, где доступен JavaScript.
Теперь, чтобы ответить на ваш вопрос: JavaScript недоступен для wp-cron, так как эти запросы выполняются исключительно на сервере, а не на каком-либо интерпретируемом HTML/JavaScript. Что можно сделать? Ну, просто запланируйте еще одно событие, если вы еще не закончили (или ваша отдельная нагрузка завершена).
Хотя wp_schedule_event() используется для повторяющихся событий, также есть wp_schedule_single_event(), который можно использовать для “еще не завершенных” рабочей нагрузки.
Скажем, вы хотите очищать свою базу данных ежедневно, рабочий процесс может выглядеть так:
wp_schedule_event() для ежедневного запуска функции clean_my_db().
Внутри clean_my_db() вы создаете массив $tables_to_clean = [‘posts’, ‘postmeta’]. Теперь вы вызываете wp_schedule_single_event(), чтобы запустить clean_my_db_table() и передать каждую из таблиц как аргумент.
clean_my_db_table(‘posts’) выполняется
clean_my_db_table(‘postmeta’) выполняется
и так далее.
В сумме: у вас есть одна функция, вызываемая wp_schedule_event(), которая является повторяющимся событием. Внутри этого вы решаете разбить рабочие нагрузки и запускать их через wp_schedule_single_event() в определенные даты/времена.
Ответ или решение
Использование wp-ajax в wp-cron может показаться непростой задачей, учитывая, что JavaScript, вызываемый через Ajax, предназначен для фронтенд-обработки и работает в браузере. В то время как wp-cron работает на серверной стороне без взаимодействия пользователя. Однако существует способ разделить ваши задачи и использовать преимущества как wp-cron, так и Ajax.
Проблема и решение
Вы создали собственный плагин для WordPress, который использует WP Ajax для разгрузки процесса и предотвращения ошибок переполнения памяти. Этот подход действительно позволяет разбивать крупные задачи на более мелкие, но WP Cron не может напрямую взаимодействовать с JavaScript. Вместо этого, вам нужно использовать серверные функции и планировщик событий WordPress.
Включение wp-cron
Для начала, давайте рассмотрим, как можно реализовать вашу логику с использованием wp_cron
:
-
Создание источника события: Используйте
wp_schedule_event()
для создания повторяющегося события, которое будет вызывать вашу основную функцию.if ( !wp_next_scheduled( 'my_cron_event' ) ) { wp_schedule_event( time(), 'hourly', 'my_cron_event' ); } add_action( 'my_cron_event', 'process_large_task' );
-
Обработка задачи: В вашей функции
process_large_task()
, вам необходимо будет реализовать логику для разбивки задачи. Например:function process_large_task() { // Логика для обработки // Проверяем, завершена ли работа $tasks_remaining = get_option('tasks_remaining', true); // Проверяем оставшиеся задачи if ( $tasks_remaining ) { // Выполняем часть работы // Например, очищаем записи таблицы clean_my_db_table(); // Обновляем количество оставшихся задач update_option('tasks_remaining', --$tasks_remaining); } else { // Убираем событие, если все задачи выполнены delete_option('tasks_remaining'); // Можно удалить само событие wp_clear_scheduled_hook('my_cron_event'); } }
-
Запланированные одиночные события: Если вы хотите разбить задачи на более мелкие куски, можете использовать
wp_schedule_single_event()
. Например, для каждой задачи:if ( $tasks_remaining ) { for ($i = 0; $i < $number_of_tasks; $i++) { wp_schedule_single_event( time() + ( $i * 60 ), 'process_single_task', array($task_id) ); } }
Затем создайте обработчик для
process_single_task
, где будет выполняться конкретная рабочая задача.
Рекомендации
-
REST API: Если ваш проект позволяет, стоит рассмотреть использование REST API как более современного решения. Вы можете вызывать серверные методы без необходимости использовать JavaScript для обработки задач, что также снизит нагрузку на сервер.
-
Оптимизация: Регулярно проверяйте настройки крона для избежания ненужных вызовов и утечек памяти. Обрабатывайте только то, что действительно необходимо.
Заключение
Использование wp-cron в WordPress с вашими задачами требует некоторого упрощения логики работы. Вместо использования JS со стороны клиента, вы можете управлять серверными функциями, чтобы планировать выполнение задач и их разбиение. Такой подход повышает стабильность работы вашего приложения и позволяет избежать ошибок переполнения памяти, сохраняя при этом производительность и эффективность работы кода.