防抖Wordpress操作钩子(或其他任何PHP函数)

时间:2018-06-21 08:18:40

标签: wordpress aggregate debouncing debounce post-meta

我有一个Wordpress插件,该插件在发布帖子/帖子后发生更改后发送发布数据。

问题是,在繁忙的Wordpress网站上可能会有很多postmeta更改,所以我想对元更新进行去抖动/节流/聚合,以单个POST调用进行,时间为1秒。

不知道如何解决这个问题,因为我已经使用异步语言已有一段时间了,并且找不到与PHP等效的setTimeout。
有任何可分享的想法吗?

add_action( 'updated_post_meta', 'a3_updated_post_meta', 10, 4 );

function a3_updated_post_meta($meta_id, $post_id, $meta_key, $meta_value){
    global $wpdb;
    global $a3_types_to_send;

    a3_write_log('---> u p d a t e d  post  m e t a');

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    $mongo_dest_address = 'http://localhost:8080/admin/dirty';
    $reason = 'edit_meta';

    $dirty_post_ids = get_option('a3_dirty_post_ids');

    if(! is_array($dirty_post_ids) ){
        $dirty_post_ids = array();
    }    

    $dirty_post_ids[] = (int) $post_id;

    update_option('a3_dirty_post_ids', array_unique($dirty_post_ids));    

    $object_type = $wpdb->get_var( $wpdb->prepare("select post_type from $wpdb->posts where ID = %d", $post_id) );

    if(in_array($object_type, $a3_types_to_send)){
        a3_send_post_trans($post_id, $reason);  
    }            
}

2 个答案:

答案 0 :(得分:1)

在PHP中没有直接的方法可以做到这一点。我向您建议的是探索其他想法,例如:

A)停止触发这些操作并每隔X秒运行cron脚本(服务器将在特定间隔内触发简单的php脚本,该脚本将处理帖子)  B)以与您现在执行的方式类似的方式触发操作,并将帖子放入特定的队列(根据您的专业知识,可以采用任何形式,从最简单的形式到例如RabbitMQ)。之后,您将不得不创建queueHandler脚本(与第一点类似),以处理来自队列的帖子。

答案 1 :(得分:0)

这就是我在save_post钩子上解决此问题的方式

    function debounce_send() {
        $send_time = get_transient('send_time');

        if($send_time) {
            wp_clear_scheduled_hook('run_send')
            wp_schedule_single_event($send_time, 'run_send');
            
        } else {
            run_send();
            set_transient('send_time', time() + 60, 60);
        }
    }
    add_action('save_post', 'debounce_send');

然后我这样做:

    function run_send() {
        // Send an email here
    }
    add_action( 'run_send', 'run_send' );

结果是,它将每60秒发送1封电子邮件,费用为最高。