[buddypress-trac] [BuddyPress Trac] #7436: Very slow check_is_friend function
buddypress-trac
noreply at wordpress.org
Wed Feb 8 03:35:28 UTC 2017
#7436: Very slow check_is_friend function
--------------------------+--------------------
Reporter: januzi_pl | Owner:
Type: defect (bug) | Status: new
Priority: low | Milestone: 2.7.5
Component: Friends | Version: 2.7
Severity: major | Resolution:
Keywords: dev-feedback |
--------------------------+--------------------
Comment (by boonebgorges):
Gah, I just left a comment, but my cookie died and I lost it :(
@dcavins is correct that this improvement to group and friendship caching
was meant to help in directories, and I think it's correct to say that it
does help rather than hurt the majority of BP sites. But it's definitely
not efficient in cases like this.
@r-a-y - The goal of caching here is to avoid 20 extra db hits in member
directories. Our current caching strategy is to first check the cache, and
then to fall back to the database if nothing's found in the cache. This
means that it's not possible to tell the difference between a cold cache
and a non-friendship without hitting the database. (It's not practical to
cache the non-friendship status of every set of non-friends.) We could
reduce the number of db hits by doing some cache-warming at the beginning
of the loop - sorta like `update_meta_cache`. But this only works well for
successful friendships. We'd maybe have to cache non-friendships
separately, perhaps non-persistently, which means it'd be impossible to
avoid hitting the db altogether for all users.
To clarify: Consider a site with three members: A, B, and C. The only
friendship is between A and B. A is logged in and views `/members/`.
Assume the cache is empty. After fetching the member IDs, we do something
like this:
{{{
// Check for uncached friendships.
$member_ids = wp_list_pluck( $members_template->members, 'ID' );
$uncached = array();
foreach ( $member_ids as $member_id ) {
// Don't check logged-in user.
if ( $member_id === $loggedin_user_id ) {
continue;
}
$cached = wp_cache_get( "$member_id:$loggedin_user_id",
'bp_friends_friendship_pair' );
if ( false === $cached ) {
$uncached[] = $member_id;
}
}
// Because the cache was empty, $uncached is [ B, C ]
if ( $member_ids ) {
$friendships = some_function_to_get_friendships_from_db( $member_ids
);
foreach ( $friendships as $friendship ) {
wp_cache_set( ... );
}
}
}}}
Either (a) we cache every non-friendship, or (b) on the next pageload,
`$member_ids` will be `[ C ]`, which will require a database hit.
Maybe this is the best we can do to account for instances where users have
many thousands of friends?
--
Ticket URL: <https://buddypress.trac.wordpress.org/ticket/7436#comment:8>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac
More information about the buddypress-trac
mailing list