Skip to content

Commit

Permalink
cache User.count_followers in memcache
Browse files Browse the repository at this point in the history
for #1149
  • Loading branch information
snarfed committed Dec 13, 2024
1 parent 4f5e868 commit 6388aab
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
12 changes: 9 additions & 3 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
OBJECT_EXPIRE_AGE = timedelta(days=90)

GET_ORIGINALS_CACHE_EXPIRATION = timedelta(days=1)
FOLLOWERS_CACHE_EXPIRATION = timedelta(hours=2)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -847,9 +848,13 @@ def profile_picture(self):
if self.obj and self.obj.as1:
return util.get_url(self.obj.as1, 'image')

# TODO: cache in memcache
@cachetools.cached(cachetools.TTLCache(50000, 60 * 60 * 2), # 2h expiration
key=lambda user: user.key.id(), lock=Lock())
# can't use functools.lru_cache here because we want the cache key to be
# just the user id, not the whole entity
@cachetools.cached(
cachetools.TTLCache(50000, FOLLOWERS_CACHE_EXPIRATION.total_seconds()),
key=lambda user: user.key.id(), lock=Lock())
@memcache_memoize(key=lambda self: self.key.id(),
expire=FOLLOWERS_CACHE_EXPIRATION)
def count_followers(self):
"""Counts this user's followers and followings.
Expand Down Expand Up @@ -1721,3 +1726,4 @@ def get_original_user_key(copy_id):
if proto and proto.LABEL != 'ui' and not proto.owns_id(copy_id):
if orig := proto.query(proto.copies.uri == copy_id).get(keys_only=True):
return orig

11 changes: 8 additions & 3 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,12 +431,17 @@ def test_count_followers(self):
Follower(from_=self.user.key, to=Fake(id='b').key).put()
Follower(from_=Fake(id='c').key, to=self.user.key).put()

# still cached
# cached in both memcache and memory
user = Web.get_by_id('y.za')
self.assertEqual((0, 0), user.count_followers())

User.count_followers.cache.clear()
del self.user
# clear memory cache, still cached in memcache
user.count_followers.cache.clear()
self.assertEqual((0, 0), user.count_followers())

# clear both
common.pickle_memcache.clear()
user.count_followers.cache.clear()
self.assertEqual((1, 2), user.count_followers())

def test_is_enabled_default_enabled_protocols(self):
Expand Down

0 comments on commit 6388aab

Please sign in to comment.