Skip to content

Commit

Permalink
reddit: cache user profile API fetches for 5m to avoid repeating them
Browse files Browse the repository at this point in the history
...when fetching multiiple comments or posts from the same author. snarfed/bridgy#1021
  • Loading branch information
snarfed committed Apr 1, 2021
1 parent d521dde commit 85ccb5a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ Changelog
* Bug fix: URL-encode list names in API calls.
* Bug fix: propagate alt text into AS1 `photo.displayName` so that it gets all the way into microformats2 JSON and HTML ([#183](https://github.com/snarfed/granary/issues/183)).
* Reddit:
* Fix `post_id()`.
* Implement `post_id()`.
* Cache user data fetched from the API for 5m to avoid repeating user profile API requests ([bridgy#1021](https://github.com/snarfed/bridgy/issues/1021)).
when fetching multiple comments or posts from the same author
* Bug fix: use 'displayName' instead of 'name' in AS1 objects for submissions.
* Bug fix: use tag URIs for activity ids.
* ActivityStreams 2:
Expand Down
25 changes: 21 additions & 4 deletions granary/reddit.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,24 @@
PRAW API docs:
https://praw.readthedocs.io/
"""

from . import source
import logging
from oauth_dropins import reddit
from oauth_dropins.webutil import appengine_info, util
import operator
import re
import urllib.parse, urllib.request
import threading

from cachetools import cachedmethod, TTLCache
from oauth_dropins import reddit
from oauth_dropins.webutil import appengine_info, util
import praw
from prawcore.exceptions import NotFound

from . import source

USER_CACHE_TIME = 5 * 60 # 5 minute expiration, in seconds
user_cache = TTLCache(1000, USER_CACHE_TIME)
user_cache_lock = threading.RLock()


class Reddit(source.Source):
"""Reddit source class. See file docstring and Source class for details."""
Expand Down Expand Up @@ -57,13 +64,23 @@ def post_id(self, url):
if len(path_parts) >= 2:
return path_parts[-2]

@cachedmethod(lambda self: user_cache, lock=lambda self: user_cache_lock,
key=lambda user: getattr(user, 'name', None))
def praw_to_actor(self, praw_user):
"""Converts a PRAW Redditor to an actor.
Makes external calls to fetch data from the Reddit API.
https://praw.readthedocs.io/en/latest/code_overview/models/redditor.html
Caches fetched user data for 5m to avoid repeating user profile API requests
when fetching multiple comments or posts from the same author. Background:
https://github.com/snarfed/bridgy/issues/1021
Ideally this would be part of PRAW, but they seem uninterested:
https://github.com/praw-dev/praw/issues/131
https://github.com/praw-dev/praw/issues/1140
Args:
user: PRAW Redditor object
Expand Down
2 changes: 2 additions & 0 deletions granary/tests/test_reddit.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ def setUp(self):
self.submission_link.selftext = ''
self.submission_link.url = 'https://reddit.com/ezv3f2'

reddit.user_cache.clear()

def test_user_url(self):
self.assert_equals('https://reddit.com/user/foo', self.reddit.user_url('foo'))

Expand Down

0 comments on commit 85ccb5a

Please sign in to comment.