【问题标题】:Run Scheduled WP Cron Tasks Right Away in WordPress立即在 WordPress 中运行计划的 WP Cron 任务
【发布时间】:2023-10-06 01:01:01
【问题描述】:

我正在尝试在安排一些操作事件后立即运行 WordPress cron 任务。通常 WordPress Cron 至少需要一个页面加载来触发计划任务。我正试着马上去做。我几乎设法做到了,如下面的代码所示。

/* Plugin Name: Sample Cron Immediate Execution  */

add_action('admin_menu', 'sample_cron_immediate_execution');
function sample_cron_immediate_execution() {
    add_options_page(
        'Sample Cron Immediate Execution', 
        'Sample Cron Immediate Execution', 
        'manage_options',
        'sample_cron_immediate_execution', 
        'sample_cron_immediate_execution_admin');
}
function sample_cron_immediate_execution_admin() {
    ?>
    <div class="wrap">
    <?php
        wp_schedule_single_event(time(), 'my_action1');
        wp_schedule_single_event(time(), 'my_action2');
        $cron_url = site_url( 'wp-cron.php?doing_wp_cron=0');
        wp_remote_post( $cron_url, array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) );
        echo 'cron tasks should be executed by now.';
    ?>
    </div>
    <?php
}

add_action('my_action1', 'myeventfunc1'); 
function myeventfunc1() {
    sleep(10); // assuming it's a heavy task 
    sample_log(date('l jS \of F Y h:i:s A'), __DIR__ . '/myevent1_log.html');
}

add_action('my_action2', 'myeventfunc2');    
function myeventfunc2() {
    sleep(10); // assuming it's a heavy task 
    sample_log(date('l jS \of F Y h:i:s A'), __DIR__ . '/myevent2_log.html');
}

function sample_log($time, $file) {
    file_put_contents($file, $time . '<br />', FILE_APPEND);
}

问题在于,当其中一项任务很繁重时,WordPress 似乎无法在一次调用wp-cron.php 中完成所有任务。当我查看核心文件的代码时,我猜测 $_GET 值 doing_wp_cron 与它有关,

其中一个cmets说

使用全局 $doing_wp_cron 锁,否则使用 GET 锁。如果没有锁,请尝试获取新锁。

我不完全明白这是什么意思。我想做的是立即执行多个计划任务,而无需打开另一个页面,而不管任务的繁重程度。

感谢您的信息。

【问题讨论】:

  • 您可以使用“真正的 cron 作业”来启动您的 WP Cron。有什么特别的原因你不做那样的事情吗?我们在几个地方使用了这种方法,它提供了一种强大的解决方案,可以以最小的干扰来缓存内容!
  • 这是一个分布式插件。是否所有系统都允许执行 cron 命令?
  • 哦,这改变了它,我“希望”它适用于您自己的应用程序。不幸的是,在大多数系统上,您需要在服务器级别运行 cron 命令,您无法真正编写“嘿,WordPress 插件,执行此服务器级别 cron!”的函数。 ://

标签: php cron wordpress


【解决方案1】:

尝试将超时更改为 30 秒。

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

【讨论】:

  • Try to change timeout to 30 seconds. -- 它只会减慢页面加载速度。
【解决方案2】:

这应该可以完成工作。

<?php
    /* Plugin Name: Sample Cron Immediate Execution  */

    add_action('admin_menu', 'sample_cron_immediate_execution');
    function sample_cron_immediate_execution() {
        add_options_page(
            'Sample Cron Immediate Execution', 
            'Sample Cron Immediate Execution', 
            'manage_options',
            'sample_cron_immediate_execution', 
            'sample_cron_immediate_execution_admin');
    }
    function sample_cron_immediate_execution_admin() {
        ?>
        <div class="wrap">
        <?php
            $cron_url = site_url( '?custom_cron=myeventfunc1');         
            wp_remote_post( $cron_url, array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) );
            $cron_url = site_url( '?custom_cron=myeventfunc2');         
            wp_remote_post( $cron_url, array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) );
            echo 'cron tasks should be executed by now.';
        ?>
        </div>
        <?php
    }

    add_action('init', 'run_customcron');
    function run_customcron() 
    {
        if (isset($_GET['custom_cron']))
        {
            call_user_func($_GET['custom_cron']);
        }
    }

    function myeventfunc1() {
        sleep(10); // assuming it's a heavy task 
        sample_log(date('l jS \of F Y h:i:s A'), __DIR__ . '/myevent1_log.html');
    }

    function myeventfunc2() {
        sleep(10); // assuming it's a heavy task 
        sample_log(date('l jS \of F Y h:i:s A'), __DIR__ . '/myevent2_log.html');
    }

    function sample_log($time, $file) {
        file_put_contents($file, $time . '<br />', FILE_APPEND);
    }

【讨论】:

  • 这是非常不安全的 - 绝不应该允许根据 GET 参数的值执行任意函数。
【解决方案3】:

如果您只安排一个事件并希望它立即运行,我不太明白为什么要使用 cron —— 为什么不直接执行该操作?

do_action('my_action1');
do_action('my_action2');

每次访问页面时,Wordpress 都会自动运行任何过期的 cron,因此我认为手动调用 wp-cron 没有任何理由。

关于你的

当其中一项任务很繁重时,WordPress 似乎无法在一次调用 wp-cron.php 中完成所有任务

comment,知道 PHP 在默认情况下会在脚本(包括 Wordpress crons)的执行时间超过 30 秒时终止执行。假设您安排了 5 个 crons,每个 crons 都需要 9 秒才能运行。前 3 个将运行,但后两个不会运行(PHP 将在第 4 个开始后不久死亡)。我使用 PHP 的 set_time_limit 函数取得了很好的效果,让我的服务器可以在 wordpress cron 中执行非常大的 cURL 请求。

还有几件事:

  • cron 应该是异步的。您正在尝试使其同步,这可能会导致显着页面加载延迟。
  • 请务必在致电do_action 之前致电add_action

【讨论】:

  • You're trying to make it synchronous, 不,我不是。这就是我尝试使用 WordPress 伪 cron 的原因,它模拟异步函数调用。 do_action('my_action1'); 它将是同步的,页面加载在操作结束之前不会完成。您是否尝试过发布的示例插件?页面加载在创建日志文件之前完成。至于set_time_limit,问题可没那么简单。请尝试将睡眠秒数减少到 5 秒左右,然后按两次重新加载按钮。它只执行第一次调用。
【解决方案4】:

为什么要重建原生调度器?这应该有效:

function my_job() {
    // heavy lifting
}
add_action( 'my_hook', 'my_job' );

wp_schedule_single_event( time(), 'my_hook', array( 'my_arg' ) );
spawn_cron();

【讨论】:

  • 这个问题的唯一真正解决方案。完美答案!
最近更新 更多