Skip to:
Content

BuddyPress.org

Changeset 8332


Ignore:
Timestamp:
04/30/2014 05:22:22 PM (10 years ago)
Author:
boonebgorges
Message:

Overhaul caching for user last_activity values

The last_activity methods in the BP_Core_User class were originally designed
without persistent caching in mind. In r8047, some minimal caching support was
introduced, but it was tacked on and incomplete. In particular, it depended
on an inconsistent structure of return values from the last_activity methods.
See #5128 for more background.

This changeset introduces a number of changes that make last_activity methods
perform more consistently, as well as full support for object caching.

  • BP_Core_User::get_last_activity() always returns a multidimensional array of last_activity arrays, keyed by user_id. This remains true even when last_activity data is being fetched only for a single user.
  • last_activity data is stored in the bp_last_activity cache bucket without the user-id-keyed wrapper.
  • BP_Core_User::get_last_activity() now uses the same caching technique as other BuddyPress and WordPress queries: detect which requested items are not yet in the cache, prime the cache for those items, and then fetch all requested values directly from the cache to build a return value.

Fixes #5590

Props imath, johnjamesjacoby for initial patches

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-core/bp-core-classes.php

    r8320 r8332  
    13221322        global $wpdb;
    13231323
    1324         if ( is_array( $user_id ) ) {
    1325             $user_ids = wp_parse_id_list( $user_id );
    1326         } else {
    1327             $user_ids = array( absint( $user_id ) );
    1328         }
     1324        // Sanitize and remove empty values
     1325        $user_ids = array_filter( wp_parse_id_list( $user_id ) );
    13291326
    13301327        if ( empty( $user_ids ) ) {
     
    13321329        }
    13331330
    1334         // get cache for single user only
    1335         // @todo Why only single user?
    1336         if ( ! is_array( $user_id ) ) {
    1337             $cache = wp_cache_get( $user_id, 'bp_last_activity' );
    1338 
    1339             if ( false !== $cache ) {
    1340                 return $cache;
    1341             }
    1342         }
    1343 
    1344         $bp = buddypress();
    1345 
    1346         $user_ids_sql = implode( ',', $user_ids );
    1347         $user_count   = count( $user_ids );
    1348 
    1349         $last_activities = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, date_recorded FROM {$bp->members->table_name_last_activity} WHERE component = %s AND type = 'last_activity' AND user_id IN ({$user_ids_sql}) LIMIT {$user_count}", $bp->members->id ) );
    1350 
    1351         // Re-key
     1331        $uncached_user_ids = bp_get_non_cached_ids( $user_ids, 'bp_last_activity' );
     1332        if ( ! empty( $uncached_user_ids ) ) {
     1333            $bp = buddypress();
     1334
     1335            $user_ids_sql = implode( ',', $uncached_user_ids );
     1336            $user_count   = count( $uncached_user_ids );
     1337
     1338            $last_activities = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, date_recorded FROM {$bp->members->table_name_last_activity} WHERE component = %s AND type = 'last_activity' AND user_id IN ({$user_ids_sql}) LIMIT {$user_count}", $bp->members->id ) );
     1339
     1340            foreach ( $last_activities as $last_activity ) {
     1341                wp_cache_set( $last_activity->user_id, array(
     1342                    'user_id'       => $last_activity->user_id,
     1343                    'date_recorded' => $last_activity->date_recorded,
     1344                    'activity_id'   => $last_activity->id,
     1345                ), 'bp_last_activity' );
     1346            }
     1347        }
     1348
     1349        // Fetch all user data from the cache
    13521350        $retval = array();
    1353         foreach ( $last_activities as $last_activity ) {
    1354             $retval[ $last_activity->user_id ] = array(
    1355                 'user_id'       => $last_activity->user_id,
    1356                 'date_recorded' => $last_activity->date_recorded,
    1357                 'activity_id'   => $last_activity->id,
    1358             );
    1359         }
    1360 
    1361         // If this was a single user query, update the cache
    1362         if ( ! is_array( $user_id ) && isset( $retval[ $user_id ] ) ) {
    1363             wp_cache_set( $user_id, $retval[ $user_id ], 'bp_last_activity' );
     1351        foreach ( $user_ids as $user_id ) {
     1352            $retval[ $user_id ] = wp_cache_get( $user_id, 'bp_last_activity' );
    13641353        }
    13651354
     
    13861375        $activity = self::get_last_activity( $user_id );
    13871376
    1388         if ( ! empty( $activity ) ) {
     1377        if ( ! empty( $activity[ $user_id ] ) ) {
    13891378            $updated = $wpdb->update(
    13901379                $table_name,
     
    14431432            );
    14441433
    1445             // setup activity array for caching
     1434            // set up activity array for caching
    14461435            // view the foreach loop in the get_last_activity() method for format
    14471436            $activity = array();
     
    14541443
    14551444        // set cache
    1456         wp_cache_set( $user_id, $activity, 'bp_last_activity' );
     1445        wp_cache_set( $user_id, $activity[ $user_id ], 'bp_last_activity' );
    14571446
    14581447        return $updated;
  • trunk/tests/testcases/core/class-bp-core-user.php

    r8326 r8332  
    159159    /**
    160160     * @group last_activity
     161     * @group cache
    161162     */
    162163    public function test_get_last_activity_store_in_cache() {
     
    176177    /**
    177178     * @group last_activity
    178      */
    179     public function test_get_last_activity_in_cache_single_user() {
     179     * @group cache
     180     */
     181    public function test_get_last_activity_store_in_cache_multiple_users() {
     182        $u1 = $this->create_user();
     183        $u2 = $this->create_user();
     184        $time = bp_core_current_time();
     185
     186        // Cache is set during user creation. Clear to reflect actual
     187        // pageload
     188        wp_cache_delete( $u1, 'bp_last_activity' );
     189        wp_cache_delete( $u2, 'bp_last_activity' );
     190
     191        // prime cache
     192        $a = BP_Core_User::get_last_activity( array( $u1, $u2 ) );
     193
     194        $this->assertSame( $a[ $u1 ], wp_cache_get( $u1, 'bp_last_activity' ) );
     195        $this->assertSame( $a[ $u2 ], wp_cache_get( $u2, 'bp_last_activity' ) );
     196    }
     197
     198    /**
     199     * @group last_activity
     200     * @group cache
     201     */
     202    public function test_get_last_activity_from_cache_single_user() {
    180203        $u    = $this->create_user();
    181204        $time = bp_core_current_time();
     
    183206        BP_Core_User::update_last_activity( $u, $time );
    184207
     208        // Cache is set during user creation. Clear to reflect actual
     209        // pageload
     210        wp_cache_delete( $u, 'bp_last_activity' );
     211
     212        // Prime cache
     213        $uncached = BP_Core_User::get_last_activity( $u );
     214
     215        // Fetch again to get from the cache
     216        $cached = BP_Core_User::get_last_activity( $u );
     217
     218        $this->assertSame( $uncached, $cached );
     219    }
     220
     221    /**
     222     * @group last_activity
     223     * @group cache
     224     */
     225    public function test_get_last_activity_in_cache_multiple_users() {
     226        $u1 = $this->create_user();
     227        $u2 = $this->create_user();
     228        $time = bp_core_current_time();
     229
     230        BP_Core_User::update_last_activity( $u1, $time );
     231        BP_Core_User::update_last_activity( $u2, $time );
     232
    185233        // Cache is set during user creation. Clear to reflect actual pageload
    186         wp_cache_delete( $u, 'bp_last_activity' );
    187 
    188         // prime cache
    189         $a = BP_Core_User::get_last_activity( $u );
    190         $b = BP_Core_User::get_last_activity( $u );
    191 
    192         $this->assertSame( $a, $b );
     234        wp_cache_delete( $u1, 'bp_last_activity' );
     235        wp_cache_delete( $u2, 'bp_last_activity' );
     236
     237        // Prime cache
     238        $uncached = BP_Core_User::get_last_activity( array( $u1, $u2 ) );
     239
     240        // Second grab will be from the cache
     241        $cached = BP_Core_User::get_last_activity( array( $u1, $u2 ) );
     242        $cached_u1 = wp_cache_get( $u1, 'bp_last_activity' );
     243
     244        $this->assertSame( $cached, $uncached );
    193245    }
    194246
Note: See TracChangeset for help on using the changeset viewer.