Skip to:
Content

BuddyPress.org

Ticket #7237: 7237.diff

File 7237.diff, 8.7 KB (added by boonebgorges, 3 years ago)
  • src/bp-activity/bp-activity-cache.php

    diff --git src/bp-activity/bp-activity-cache.php src/bp-activity/bp-activity-cache.php
    index a3a7241..a647e1a 100644
    function bp_activity_clear_cache_for_deleted_activity( $deleted_ids ) { 
    6363        }
    6464}
    6565add_action( 'bp_activity_deleted_activities', 'bp_activity_clear_cache_for_deleted_activity' );
     66
     67/**
     68 * Reset 'last_changed' cache incrementor.
     69 *
     70 * @since 2.7.0
     71 */
     72function bp_activity_reset_cache_incrementor() {
     73        wp_cache_delete( 'last_changed', 'bp_activity' );
     74}
     75add_action( 'bp_activity_delete', 'bp_activity_reset_cache_incrementor' );
     76add_action( 'bp_activity_add', 'bp_activity_reset_cache_incrementor' );
  • src/bp-activity/classes/class-bp-activity-activity.php

    diff --git src/bp-activity/classes/class-bp-activity-activity.php src/bp-activity/classes/class-bp-activity-activity.php
    index c24a533..e62b398 100644
    class BP_Activity_Activity { 
    645645                         */
    646646                        $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
    647647
    648                         $activity_ids = $wpdb->get_col( $activity_ids_sql );
     648                        $cached = bp_core_get_cached_ids( $activity_ids_sql, 'bp_activity' );
     649                        if ( false === $cached ) {
     650                                $activity_ids = $wpdb->get_col( $activity_ids_sql );
     651                                bp_core_set_cached_ids( $activity_ids_sql, 'bp_activity', $activity_ids );
     652                        } else {
     653                                $activity_ids = $cached;
     654                        }
    649655
    650656                        $retval['has_more_items'] = ! empty( $per_page ) && count( $activity_ids ) > $per_page;
    651657
  • src/bp-core/bp-core-cache.php

    diff --git src/bp-core/bp-core-cache.php src/bp-core/bp-core-cache.php
    index f4bbab0..c4c7d27 100644
    function bp_update_meta_cache( $args = array() ) { 
    262262
    263263        return $cache;
    264264}
     265
     266/**
     267 * Gets a cached list of IDs matching a query key.
     268 *
     269 * A utility function for use by query methods like BP_Activity_Activity::get().
     270 *
     271 * @since 2.7.0
     272 *
     273 * @param string $key   Unique key for the query. Usually a SQL string.
     274 * @param string $group Cache group. Eg 'bp_activity'.
     275 * @return array|bool False if no cached values are found, otherwise an array of IDs.
     276 */
     277function bp_core_get_cached_ids( $key, $group ) {
     278        $cache_key = bp_core_get_incremented_cache_key( $key, $group );
     279        return wp_cache_get( $cache_key, $group );
     280}
     281
     282/**
     283 * Caches a list of IDs matched by an object query.
     284 *
     285 * A utility function for use by query methods like BP_Activity_Activity::get().
     286 *
     287 * @since 2.7.0
     288 *
     289 * @param string $key   Unique key for the query. Usually a SQL string.
     290 * @param string $group Cache group. Eg 'bp_activity'.
     291 * @param array  $ids   Array of IDs.
     292 * @return bool
     293 */
     294function bp_core_set_cached_ids( $key, $group, $ids ) {
     295        $cache_key = bp_core_get_incremented_cache_key( $key, $group );
     296        return wp_cache_set( $cache_key, $ids, $group );
     297}
     298
     299/**
     300 * Gets the key to be used when caching an ID query using WP's wp_cache_*() functions.
     301 *
     302 * The $key is hashed with a component-specific incrementor, which is used to
     303 * invalidate multiple caches at once.
     304 *
     305 * @since 2.7.0
     306 *
     307 * @param string $key   Unique key for the query. Usually a SQL string.
     308 * @param string $group Cache group. Eg 'bp_activity'.
     309 * @return string
     310 */
     311function bp_core_get_incremented_cache_key( $key, $group ) {
     312        $incrementor = bp_core_get_incrementor( $group );
     313        $cache_key = md5( $key . $incrementor );
     314        return $cache_key;
     315}
     316
     317/**
     318 * Gets a group-specific cache incrementor.
     319 *
     320 * The incrementor is paired with query identifiers (like SQL strings) to
     321 * create cache keys that can be invalidated en masse.
     322 *
     323 * If an incrementor does not yet exist for the given `$group`, one will
     324 * be created.
     325 *
     326 * @since 2.7.0
     327 *
     328 * @param string $group Cache group. Eg 'bp_activity'.
     329 * @return string
     330 */
     331function bp_core_get_incrementor( $group ) {
     332        $incrementor = wp_cache_get( 'last_changed', $group );
     333        if ( ! $incrementor ) {
     334                $incrementor = microtime();
     335                wp_cache_set( 'last_changed', $incrementor, $group );
     336        }
     337
     338        return $incrementor;
     339}
  • tests/phpunit/testcases/activity/cache.php

    diff --git tests/phpunit/testcases/activity/cache.php tests/phpunit/testcases/activity/cache.php
    index 0e4c6dc..c185bbd 100644
    class BP_Tests_Activity_Cache extends BP_UnitTestCase { 
    8383
    8484                $this->assertSame( 'bar foo', $a_fp['activities'][0]->content );
    8585        }
     86
     87        /**
     88         * @ticket BP7237
     89         * @ticket BP6643
     90         */
     91        public function test_query_should_be_cached() {
     92                global $wpdb;
     93
     94                $u = $this->factory->user->create();
     95                $a = $this->factory->activity->create( array(
     96                        'component'     => buddypress()->activity->id,
     97                        'type'          => 'activity_update',
     98                        'user_id'       => $u,
     99                        'content'       => 'foo bar',
     100                ) );
     101
     102                $activity_args = array(
     103                        'per_page' => 10,
     104                        'fields' => 'ids',
     105                        'count_total' => false,
     106                );
     107
     108                $a1 = bp_activity_get( $activity_args );
     109
     110                $num_queries = $wpdb->num_queries;
     111
     112                $a2 = bp_activity_get( $activity_args );
     113
     114                $this->assertEqualSets( $a1, $a2 );
     115                $this->assertSame( $num_queries, $wpdb->num_queries );
     116        }
     117
     118        /**
     119         * @ticket BP7237
     120         * @ticket BP6643
     121         */
     122        public function test_query_cache_should_be_skipped_for_different_query_params() {
     123                global $wpdb;
     124
     125                $u = $this->factory->user->create();
     126                $a = $this->factory->activity->create( array(
     127                        'component'     => buddypress()->activity->id,
     128                        'type'          => 'activity_update',
     129                        'user_id'       => $u,
     130                        'content'       => 'foo bar',
     131                ) );
     132
     133                $activity_args = array(
     134                        'per_page' => 10,
     135                        'fields' => 'ids',
     136                        'count_total' => false,
     137                );
     138
     139                $a1 = bp_activity_get( $activity_args );
     140
     141                $num_queries = $wpdb->num_queries;
     142
     143                $activity_args['per_page'] = 5;
     144                $a2 = bp_activity_get( $activity_args );
     145
     146                $this->assertEqualSets( $a1, $a2 );
     147                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     148        }
     149
     150        /**
     151         * @ticket BP7237
     152         * @ticket BP6643
     153         */
     154        public function test_query_cache_should_be_invalidated_by_activity_add() {
     155                global $wpdb;
     156
     157                $u = $this->factory->user->create();
     158                $a1 = $this->factory->activity->create( array(
     159                        'component'     => buddypress()->activity->id,
     160                        'type'          => 'activity_update',
     161                        'user_id'       => $u,
     162                        'content'       => 'foo bar',
     163                ) );
     164
     165                $activity_args = array(
     166                        'per_page' => 10,
     167                        'fields' => 'ids',
     168                        'count_total' => false,
     169                );
     170
     171                $q1 = bp_activity_get( $activity_args );
     172
     173                // Bust the cache.
     174                $a2 = $this->factory->activity->create( array(
     175                        'component'     => buddypress()->activity->id,
     176                        'type'          => 'activity_update',
     177                        'user_id'       => $u,
     178                        'content'       => 'foo bar',
     179                ) );
     180
     181                $num_queries = $wpdb->num_queries;
     182
     183                $q2 = bp_activity_get( $activity_args );
     184
     185                $expected = array( $a1, $a2 );
     186
     187                $this->assertEqualSets( $expected, $q2['activities'] );
     188                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     189        }
     190
     191        /**
     192         * @ticket BP7237
     193         * @ticket BP6643
     194         */
     195        public function test_query_cache_should_be_invalidated_by_activity_edit() {
     196                global $wpdb;
     197
     198                $u = $this->factory->user->create();
     199                $a = $this->factory->activity->create( array(
     200                        'component'     => buddypress()->activity->id,
     201                        'type'          => 'activity_update',
     202                        'user_id'       => $u,
     203                        'content'       => 'foo bar',
     204                ) );
     205
     206                $activity_args = array(
     207                        'per_page' => 10,
     208                        'fields' => 'ids',
     209                        'count_total' => false,
     210                );
     211
     212                $q1 = bp_activity_get( $activity_args );
     213
     214                // Bust the cache.
     215                $this->factory->activity->create( array(
     216                        'id'            => $a,
     217                        'component'     => buddypress()->activity->id,
     218                        'type'          => 'activity_update',
     219                        'user_id'       => $u,
     220                        'content'       => 'foo bar baz',
     221                ) );
     222
     223                $num_queries = $wpdb->num_queries;
     224
     225                $q2 = bp_activity_get( $activity_args );
     226
     227                $this->assertEqualSets( $q1, $q2 );
     228                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     229        }
     230
     231        /**
     232         * @ticket BP7237
     233         * @ticket BP6643
     234         */
     235        public function test_query_cache_should_be_invalidated_by_activity_delete() {
     236                global $wpdb;
     237
     238                $u = $this->factory->user->create();
     239                $a = $this->factory->activity->create( array(
     240                        'component'     => buddypress()->activity->id,
     241                        'type'          => 'activity_update',
     242                        'user_id'       => $u,
     243                        'content'       => 'foo bar',
     244                ) );
     245
     246                $activity_args = array(
     247                        'per_page' => 10,
     248                        'fields' => 'ids',
     249                        'count_total' => false,
     250                );
     251
     252                $q1 = bp_activity_get( $activity_args );
     253
     254                // Bust the cache.
     255                bp_activity_delete( array(
     256                        'id' => $a,
     257                ) );
     258
     259                $num_queries = $wpdb->num_queries;
     260
     261                $q2 = bp_activity_get( $activity_args );
     262
     263                $this->assertEqualSets( array(), $q2['activities'] );
     264                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     265        }
    86266}