Skip to content

Commit e3ce148

Browse files
authored
Merge pull request #353 from steemit/optimize_get_ranked_posts
optimize_get_ranked_posts
1 parent 8d0c9c8 commit e3ce148

1 file changed

Lines changed: 53 additions & 5 deletions

File tree

hive/server/bridge_api/methods.py

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Bridge API public endpoints for posts"""
22

3+
import hashlib
34
import hive.server.bridge_api.cursor as cursor
45
from hive.server.bridge_api.objects import load_posts, load_posts_reblogs, load_profiles
56
from hive.server.common.helpers import (
@@ -11,6 +12,7 @@
1112
from hive.server.hive_api.common import get_account_id
1213
from hive.server.hive_api.objects import _follow_contexts
1314
from hive.server.hive_api.community import list_top_communities
15+
from hive.server.db import CACHE_NAMESPACE
1416

1517
#pylint: disable=too-many-arguments, no-else-return
1618

@@ -80,16 +82,62 @@ async def get_ranked_posts(context, sort, start_author='', start_permlink='',
8082

8183
assert sort in ['trending', 'hot', 'created', 'promoted',
8284
'payout', 'payout_comments', 'muted'], 'invalid sort'
85+
86+
# Validate and normalize parameters
87+
start_author = valid_account(start_author, allow_empty=True)
88+
start_permlink = valid_permlink(start_permlink, allow_empty=True)
89+
limit = valid_limit(limit, 100)
90+
tag = valid_tag(tag, allow_empty=True)
91+
92+
# Generate cache key (based on all query parameters, excluding observer
93+
# as it only affects personalized content)
94+
cache_key_parts = [
95+
'get_ranked_posts',
96+
sort,
97+
start_author or '',
98+
start_permlink or '',
99+
str(limit),
100+
tag or '',
101+
]
102+
cache_key_str = '_'.join(cache_key_parts)
103+
# Use hash to shorten overly long cache keys
104+
cache_key = 'bridge_get_ranked_posts_' + hashlib.md5(cache_key_str.encode()).hexdigest()
105+
106+
# Set different cache TTL based on sort type (in seconds)
107+
cache_ttl_map = {
108+
'created': 3, # 3 seconds cache
109+
'trending': 300, # 300 seconds cache
110+
'hot': 300, # 300 seconds cache
111+
'promoted': 300, # 300 seconds cache
112+
'payout': 30, # 30 seconds cache
113+
'payout_comments': 30, # 30 seconds cache
114+
'muted': 600, # 600 seconds cache
115+
}
116+
cache_ttl = cache_ttl_map.get(sort, 60) # Default 60 seconds
117+
118+
# Try to get result from cache
119+
if db.redis_cache is not None:
120+
cached_result = await db.redis_cache.get(cache_key, namespace=CACHE_NAMESPACE)
121+
if cached_result is not None:
122+
return cached_result
123+
124+
# Cache miss, execute query
83125
ids = await cursor.pids_by_ranked(
84126
context['db'],
85127
sort,
86-
valid_account(start_author, allow_empty=True),
87-
valid_permlink(start_permlink, allow_empty=True),
88-
valid_limit(limit, 100),
89-
valid_tag(tag, allow_empty=True),
128+
start_author,
129+
start_permlink,
130+
limit,
131+
tag,
90132
observer_id)
91133

92-
return await load_posts(context['db'], ids)
134+
result = await load_posts(context['db'], ids)
135+
136+
# Store result in cache
137+
if db.redis_cache is not None:
138+
await db.redis_cache.set(cache_key, result, ttl=cache_ttl, namespace=CACHE_NAMESPACE)
139+
140+
return result
93141

94142
@return_error_info
95143
async def get_account_posts(context, sort, account, start_author='', start_permlink='',

0 commit comments

Comments
 (0)