Как убедиться, что задача WP-CRON проходит через все записи?

Вопрос или проблема

Я использую WP-Crontrol и у меня есть несколько CRON-задач, которые выполняются ежедневно для проверки возраста постов. Если посту больше 2 дней, он будет удалён.

Это работает, но по какой-то причине удаляются только некоторые посты старше трёх дней. Некоторые всё ещё остаются опубликованными.

Наверное, это связано с тем, что на сайте много постов, около 3000. Есть ли способ сделать мою CRON-задачу более эффективной?

Вот текущий код, который у меня есть:

class EventsWPCron {

    public function __construct() {

        if ( ! wp_next_scheduled( 'trash_old_events' ) ) {
            wp_schedule_event( time(), 'daily', 'trash_old_events' );
        }

        add_action( 'trash_old_events', array( $this, 'delete_events' ) ); 

    }

    public function delete_events() {
        $args = array(
            'post_type' => 'event',
            'post_status' => 'publish',
            'posts_per_page' => -1,
            'date_query' => array(
                array(
                    'before' => '2 дня назад'
                )
            )
        ); 

        $query = new WP_Query( $args );
        $posts = $query->get_posts();

        foreach( $posts as $post ) { 
            wp_delete_post( $post->ID, true );
        }


    }     

}

new EventsWPCron();

Вы не указываете количество постов, которые хотите получить из запроса, поэтому по умолчанию используется то, что вы установили в Настройки > Чтение.

Если вы хотите получить все, что соответствует вашим критериям, добавьте 'posts_per_page' => -1 к аргументам вашего запроса.

Практически всегда для PHP-скриптов установлен лимит времени. Если скрипт выполняется дольше лимита, он останавливается.

Так что если есть много постов для удаления, то есть вероятность, что скрипт остановится, поэтому он удаляет только часть из них.

Но делать это таким образом тоже не очень эффективно – что если будет много постов, так что они не поместятся в лимит памяти?

Гораздо лучшим подходом было бы запускать ваше cron-событие чаще и удалять только часть старых постов. Это будет гораздо лучше для сервера тоже…

Так что вместо того, чтобы запускать его ежедневно, запускайте его каждый час и установите явный лимит в запросе. Скажем, в среднем нужно удалить 1000 постов. Ваш скрипт должен удалять 42 поста каждый час. Давайте установим это на 100 – таким образом, вы будете уверены, что все они будут удалены.

А если их нужно удалить быстрее, тогда установите cron-событие так, чтобы оно выполнялось еще чаще – каждые 5 минут?

PS. Есть ещё один момент, который стоит учесть. Если старые посты не должны отображаться на сайте, то я бы модифицировал запросы таким образом, чтобы эти посты игнорировались. Полагаться на cron в этом случае не будет очень хорошей идеей (удаление постов может занять время, cron может не вызваться и так далее…). Конечно, вы все равно можете удалить их после того, как они будут проигнорированы всеми запросами на сайте…

Ответ или решение

Чтобы гарантировать, что задача WP-Cron проходит через все посты на вашем сайте и удаляет те, которые старше двух дней, рекомендуется оптимизировать вашу текущую реализацию кода. В этом ответе мы рассмотрим несколько важных аспектов, которые помогут вам добиться более эффективного выполнения этой задачи.

1. Проблемы с производительностью

Одна из основных причин, по которой ваши задачи не обрабатываются полностью, заключается в том, что скрипты PHP имеют лимиты по времени выполнения. Если количество постов для удаления превышает эти ограничения, процесс может быть прерван. В случае, когда на вашем сайте присутствует около 3000 постов, это может привести к проблемам, особенно если многие из них необходимо удалить одновременно.

2. Оптимизация WP-Cron

Существует несколько стратегий для улучшения работы Cron-задачи:

  • Частое выполнение Cron: Вместо ежедневного запуска задач, рассмотрите возможность их запуска чаще. Например, можно настроить задачу на запуск каждые 5-10 минут. Это поможет распределить нагрузку и уменьшить вероятность превышения лимитов по времени выполнения.

  • Постраничная обработка: Вместо того, чтобы пытаться удалить все старые посты за один раз, сделайте это порциями. Установите лимит на количество постов, удаляемых за одно выполнение задачи. Например, можно удалить только 100 постов за раз. Это можно реализовать, добавив параметр 'posts_per_page' => 100 в вашу текущую реализацию.

3. Пример исправленного кода

Вот пример доработанного кода для вашей задачи:

class EventsWPCron {

    public function __construct() {
        if ( ! wp_next_scheduled( 'trash_old_events' ) ) {
            wp_schedule_event( time(), 'hourly', 'trash_old_events' );
        }

        add_action( 'trash_old_events', array( $this, 'delete_events' ) ); 
    }

    public function delete_events() {
        //.query for posts older than 2 days
        $args = array(
            'post_type' => 'event',
            'post_status' => 'publish',
            'posts_per_page' => 100, // Ограничиваем количество постов
            'date_query' => array(
                array(
                    'before' => '2 days ago'
                )
            )
        );

        $query = new WP_Query( $args );
        $posts = $query->get_posts();

        foreach( $posts as $post ) { 
            wp_delete_post( $post->ID, true );
        }

        // Если ещё остались посты для удаления, добавим задачу в очередь
        if ( count($posts) === 100 ) {
            // Можно добавить другую логику для повторного выполнения задачи
            // Например, можете вызвать delete_events() еще раз для следующей партии
        }
    }
}

new EventsWPCron();

4. Дополнительные рекомендации

  • Режимы отображения постов: Если старые посты не должны отображаться на сайте, можно рассмотреть возможность использования пользовательского поля или таксономии для их временного скрытия, что позволит обойти задержки, связанные с Cron.

  • Мониторинг состояния Cron: Используйте WP-Crontrol для мониторинга и управления выполнением задач, чтобы убедиться, что они выполняются успешно.

Заключение

Оптимизация выполнения задач Cron не только улучшит производительность вашего сайта, но и повысит его стабильность. С учетом предлагаемой архитектуры и примера исправленного кода, вы сможете эффективно управлять удалением устаревших постов, нивелируя воздействия сервера и временные ограничения. Все эти изменения помогут улучшить пользовательский опыт и общую безопасность вашего сайта.

Следуя этим рекомендациям, вы сможете значительно повысить эффективность работы вашего WP-Cron и обеспечить полное удаление старых постов.

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

Капча загружается...