WP Cron не виконується, коли минає час


16

Мета

Я хочу використовувати wp_schedule_single_event( )для виконання однієї події, яка надсилає мені електронне повідомлення 8 хвилин після того, як користувач подає форму.

Питання

Наступний код є в моєму functions.php:

function nkapi_send_to_system( $args ) {
  wp_mail( 'xxx', 'xxx', $args );
}

add_action( 'nkapi_send', 'nkapi_send_to_system' );

function schedule_event( $id ) {
  wp_schedule_single_event( current_time( 'timestamp' ) + 480, 'nkapi_send', array( $id ) );
}

І наступний код використовується для виклику schedule-event:

schedule_event( $_SESSION['insert_id'] ); // the $_SESSION var contains an INT

Почекавши дещо більше 8 хвилин, у моїй вхідній пошті не було електронної пошти.

Що я спробував

За допомогою додатка Core Control можна побачити, на які заплановані завдання cron.

Основний екран управління

Після декількох змін мені вдалося отримати їх цілком коректними, а ще краще, коли я натиснув "Виконати зараз", я фактично отримав електронну пошту у свою поштову скриньку.

Але чому крон не виконується, коли я відвідую свій сайт через 8 хвилин. Що можливо не в цьому коді? Мушу сказати, що це вперше я використовую WP Cron.

Я спробував більше

Після коментаря vancoder id вирішив перевірити, чи працює код, якщо я поставив наступний код безпосередньо у functions.php:

function schedule_event( $id ) {
  wp_schedule_single_event( time(), 'nkapi_send', array( $id ) );
}

if ( isset( $_SESSION['insert_id'] ) ) {
  if ( ! array_key_exists( 'insert_scheduled', $_SESSION ) || $_SESSION['insert_scheduled'] != $_SESSION['insert_id'] ) {
    schedule_event( $_SESSION['insert_id'] );
    $_SESSION['insert_scheduled'] = $_SESSION['insert_id'];
  }
}

Мінус цього коду полягає в тому, що перед виконанням цього коду користувач повинен перейти на іншу сторінку. Але з іншого боку, це не працює, і це не буде моїм першим випуском ...


1
Де і як schedule_event( $_SESSION['insert_id'] );звільняють?
vancoder

Короткий код включає в себе окремий файл (з формою в ньому) на сторінці, коли в цій формі розміщено перезавантаження сторінки, той самий файл виконує schedule_event( ), скажімо, вгорі включеного файлу, завантаженого цим штрих-кодом.
Майк Мадерн

Чи працюють якісь крони? wp_version_check тощо?
vancoder

У мене не було жодної крони на роботі. У чому може бути проблема цього?
Майк Мадерн

Для підтвердження - навіть основні завдання Cron не вдається?
vancoder

Відповіді:


8

По-перше, ви можете підтвердити, що у вас немає увімкнених плагінів кешування? Плагіни кешування можуть перешкоджати роботі з cron, оскільки вашим відвідувачам надається не активна сторінка, а кешована версія вашої сторінки.

Якщо у вас увімкнено плагін кешування, ви можете вибрати одну зі своїх сторінок, додати виключення до налаштувань додатка кешування для цієї сторінки, щоб він ніколи не кешувався.

Тоді вам доведеться вручну створити роботу cron (використовуючи cpanel, якщо ви перебуваєте у спільному середовищі хостингу або з терміналу, якщо це VPS / виділений сервер), який відвідуватиме цю сторінку кожні кілька хвилин.

Я сподіваюся, що це допомагає!


У мене ввімкнено плагін кешування! Точний кеш W3, якщо бути точним
Майк Мадерн

14

По-перше, визначте власні графіки роботи cron.

add_filter('cron_schedules', array($this, 'cron_schedules'));

public function cron_schedules($schedules){
    $prefix = 'cron_';// Avoid conflict with other crons. Example Reference: cron_30_mins
    $schedule_options = array(
        '30_mins' => array(
            'display' => '30 Minutes',
            'interval' => '1800'
        ),
        '1_hours' => array(
            'display' => 'Hour',
            'interval' => '3600'
        ),
        '2_hours' => array(
            'display' => '2 Hours',
            'interval' => '7200'
        )
    );
    /* Add each custom schedule into the cron job system. */
    foreach($schedule_options as $schedule_key => $schedule){
        $schedules[$prefix.$schedule_key] = array(
            'interval' => $schedule['interval'],
            'display' => __('Every '.$schedule['display'])
        );
     }
     return $schedules;
}

Вам потрібно вирішити, де і коли насправді планувати подію.

Ось лише приклад фрагмента коду, який робить виклик методу користувацького класу:

$schedule = $this->schedule_task(array(
    'timestamp' => current_time('timestamp'), // Determine when to schedule the task.
    'recurrence' => 'cron_30_mins',// Pick one of the schedules set earlier.
    'hook' => 'custom_imap_import'// Set the name of your cron task.
));

Ось код, який насправді планує подію:

private function schedule_task($task){
    /* Must have task information. */
    if(!$task){
        return false;
    }
    /* Set list of required task keys. */
    $required_keys = array(
        'timestamp',
        'recurrence',
        'hook'
    );
    /* Verify the necessary task information exists. */
    $missing_keys = array();
    foreach($required_keys as $key){
        if(!array_key_exists($key, $task)){
            $missing_keys[] = $key;
        }
    }
    /* Check for missing keys. */
    if(!empty($missing_keys)){
        return false;
    }
    /* Task must not already be scheduled. */
    if(wp_next_scheduled($task['hook'])){
        wp_clear_scheduled_hook($task['hook']);
    }
    /* Schedule the task to run. */
    wp_schedule_event($task['timestamp'], $task['recurrence'], $task['hook']);
    return true;
}

Тепер все, що вам потрібно зробити, - це зателефонувати на ім’я вашої спеціальної задачі cron. У цьому прикладі назва завдання cron є custom_imap_import.

add_action('custom_imap_import', array($this, 'do_imap_import'));

public function do_imap_import(){
    // .... Do stuff when cron is fired ....
}

Тож у цьому прикладі $this->do_imap_import();називається кожні 30 хвилин (якщо припустити, що у вас достатньо трафіку на ваш веб-сайт).


Примітки

Потрібна візит на сторінку, щоб ваш крон вистрілив у правильний час.

Приклад: Якщо ви запланували завдання з інтервалом 30 хвилин, але ніхто не відвідував ваш сайт протягом 4 годин, ваша робота із крон не буде звільнена, поки цей відвідувач не прийде на ваш сайт через 4 години. Якщо вам справді потрібна робота, яку ви знімаєте кожні 30 хвилин, радимо налаштувати законну роботу з допомогою свого постачальника веб-хостингу, щоб відвідувати ваш веб-сайт через потрібні інтервали.

Завдання WordPress cron не роблять ваш веб-сайт повільним!

Можливо, ви замислюєтеся про те, що якщо виконувати сценарій cron потрібно багато часу, то відвідувачам доведеться чекати, поки сценарій буде виконаний. Ні! Як це можливо? Якщо ви подивитесь на wp-cron.phpфайл, ви знайдете рядок

ignore_user_abort(true);

Це php.iniконфігурація, яка встановлює, що якщо ви припините завантажувати сайт / скрипт, сценарій не припинить виконання.

Якщо ви подивитесь на wp-includes/cron.phpфайл, ви знайдете такий рядок:

wp_remote_post( $cron_url, 
array('timeout' => 0.01,
 'blocking' => false, 
 'sslverify' => apply_filters('https_local_ssl_verify', true)) );

Це означає , що WordPress чекатиме тільки 0,01 секунди для запуску виконання , то вона буде перервана , але , як ви встановили ignore_user_abortна trueсценарій буде виконуватися. Ця функціональність є величезною перевагою для виконання великих сценаріїв у завданнях cron WordPress.

Функції, доступні для допомоги:


6
Це надзвичайно вичерпна відповідь, яка, наскільки я бачу, не вдається вирішити власне питання - саме тому всі заплановані завдання (включаючи основні завдання) не вдається.
vancoder

Ця відповідь спрямована на користь користувача в правильному напрямку для правильного розуміння та планування завдань WordPress cron.
Майкл Еклунд

4
Це точно допомогло мені дуже добре зрозуміти графіки роботи cron з WordPress
Mike Madern

2
Майкл, ти повинен відповідати частіше. Великий +1
кайзер

1
Я думаю, що WP_Cronвикористовує GMT під кришкою, як і решта WP, тому краще було запланувати першу подію time()замість current_time().
Іван Данн

3

WordPress Cron дозволяє планувати завдання, але вони виконуватимуться лише за наявності запиту на сайт. Кожен запит, який отримає WordPress, перевірить, чи є завдання Cron для обробки, і якщо це запускає запит на /wp-cron.php?doing_wp_cronасинхронну обробку завдання. Якщо запланований початок роботи проходить без запиту, процес крона не буде запущений.

Оскільки ви можете бачити та виконувати заплановані завдання, можливо, немає запитів, які запускають роботу cron, особливо якщо ви використовуєте плагін кешування. Найкращий варіант для завантаження цього на більш регулярний графік - відключити перевірку за замовчуванням у WordPress та використовувати crontab.

Спочатку вимкніть перевірку за замовчуванням (що може трохи допомогти з ефективністю клієнта), додайте наступне до wp-config.php:

// Disable default check for WordPress cron jobs on page loads
define( 'DISABLE_WP_CRON', true );

Далі ви створюєте завдання для отримання wp-cron.phpсторінки раз на хвилину для обробки будь-яких завдань на зворотному кінці, з командного рядка введіть, crontab -eа потім додайте рядок, який виглядає наступним чином:

*/1 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron=$(date +\%s.\%N) >/dev/null 

2
Якщо ви не присвоюєте значенню doing_wp_cron, це, швидше за все, може призвести до того, що завдання виконуються іноді двічі. Використовуйте doing_wp_cron=$(date +\%s.\%N)для запобігання цього.
Олександр Сад

0

Переконайтесь, що DISABLE_WP_CRON не встановлено у вашій конфігурації.

Якщо цього не зробити, спробуйте відключити всі плагіни (крім основного контролю - хоча я б використовував wp-crontrol) і подивіться, чи працюють ваші основні завдання. Якщо вони є, ви десь відчуваєте втручання плагінів.

Аналогічно спробуйте переключитися на стандартну двадцять щось.

Якщо жодне з них не має ніякого значення, швидше за все, це проблема хостингу.


У мене нічого не DISABLE_WP_CRONвстановлено wp-config.php, я спробую більше речей і повернусь пізніше
Майк Мадрен

0

Перевірте будь-який плагін, який приховує Wordpress.

Як зрозуміти, чи це проблема?

  1. Перейдіть до http (s): //yoursite.com/wp-cron.php Ви повинні побачити порожню сторінку. Зовсім порожній.
  2. Крім того, ви повинні побачити в менеджері завдань Cron час у розділі "Наступне виконання": Задача Cron запланована - якщо wp-cron.php працює належним чином (не лише текст "У черзі" - але і заданий час - для деяких записів "У черзі" іноді добре, але якщо це єдине ви бачите -> ваш крон не працює.)

+1. Не вірте жодним плагінам, які «перевіряють, чи працює cron» - наприклад, плагін WP Cron checker status показав, що cron працює. Але насправді цього не сталося. Що б це не показувало - повірте своїм очам, а не цьому плагіну!

Висновок: Якщо це помилка 404 - вимкніть а) не тільки кешування плагінів, як пропонують інші, б), але й будь-які додатки, які приховують Wordpress.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.