【问题标题】:Debounce Wordpress action hook (or any other PHP function)Debounce Wordpress 动作钩子(或任何其他 PHP 函数)
【发布时间】:2018-11-30 11:59:05
【问题描述】:

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

问题是在繁忙的 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);  
    }            
}

【问题讨论】:

    标签: wordpress aggregate debouncing debounce post-meta


    【解决方案1】:

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

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

    【讨论】:

    • 什么是最快速的 RabbitMQ 方案,适用于“即发即忘”类型的发布者?我已经实现了基本场景,但它似乎仍然为一个请求中的大约 20 次 postmeta 调用增加了 5-6 秒。
    • 我想我必须看到它才能知道,但您是在谈论运行时的 5-6 还是在 5-6 秒后触发?
    • 感谢@Owi,事实证明,您对 Rabbit 的想法从我的请求中减少了 5-6 秒,而其他 5 秒与 update_option 调用有关,而不是 RabbitMQ 调用,所以我将您的答案标记为解决方案。
    【解决方案2】:

    这就是我在 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 封电子邮件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      相关资源
      最近更新 更多