-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #521 from openedx/saleem-latif/ENT-9622
ENT-9622: Added caching for API endpoints related to advanced analytics.
- Loading branch information
Showing
7 changed files
with
135 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
""" | ||
Caching related utility classes and functions. | ||
""" | ||
import hashlib | ||
|
||
from edx_django_utils.cache import TieredCache | ||
|
||
DEFAULT_TIMEOUT = 60 * 60 # 1 hour | ||
|
||
|
||
def get_key(*args, **kwargs): | ||
""" | ||
Get MD5 encoded cache key for given positional and keyword arguments. | ||
MD5 encrytion is applied to a key that is generated by concatenating the positional and keyword arguments. | ||
Following is the format of the generated key from arguments before applying the MD5 encryption. | ||
arg1__arg2__key1:value1__key2:value2 ... | ||
Example: | ||
>>> get_key('ecommerce', site_domain='example.com', resource='catalogs') | ||
1892cd85a30b8fc9180369c17b472c38 | ||
>>> # The generated key for the above call before applying MD5 encryption will be as follows | ||
>>> # "ecommerce__site_domain:example.com__resource:catalogs" | ||
Arguments: | ||
*args: Arguments that need to be present in cache key. | ||
**kwargs: Key word arguments that need to be present in cache key. | ||
Returns: | ||
(str): An MD5 encoded key uniquely identified by the key word arguments. | ||
""" | ||
key = '{}__{}'.format( | ||
'__'.join(map(str, args)), | ||
'__'.join(['{}:{}'.format(item, str(value)) for item, value in kwargs.items()]) | ||
) | ||
|
||
return hashlib.md5(key.encode('utf-8')).hexdigest() | ||
|
||
|
||
def get(key): | ||
""" | ||
Get value from cache for given key. | ||
Returns: | ||
(CachedResponse): CachedResponse object. | ||
""" | ||
return TieredCache.get_cached_response(key) | ||
|
||
|
||
def set(key, value, timeout=DEFAULT_TIMEOUT): # pylint: disable=redefined-builtin | ||
""" | ||
Set value in cache for given key. | ||
Arguments: | ||
key (str): Cache key. | ||
value (object): Value to be stored in cache. | ||
timeout (int): Cache timeout in seconds. | ||
""" | ||
TieredCache.set_all_tiers(key, value, django_cache_timeout=timeout) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
""" | ||
Decorators for caching the result of a function. | ||
""" | ||
from functools import wraps | ||
from logging import getLogger | ||
|
||
from enterprise_data import cache | ||
|
||
LOGGER = getLogger(__name__) | ||
|
||
|
||
def cache_it(timeout=cache.DEFAULT_TIMEOUT): | ||
""" | ||
Function to return the decorator to cache the result of a method. | ||
Note: This decorator will only work for class methods. | ||
Arguments: | ||
timeout (int): Cache timeout in seconds. | ||
Returns: | ||
(function): Decorator function. | ||
""" | ||
|
||
def inner_decorator(func): | ||
@wraps(func) | ||
def wrapper(self, *args, **kwargs): | ||
""" | ||
Wrapper function to cache the result of the function. | ||
""" | ||
cache_key = cache.get_key(func.__name__, *args, **kwargs) | ||
cached_response = cache.get(cache_key) | ||
if cached_response.is_found: | ||
LOGGER.info("[ANALYTICS]: Cache hit for key: (%s)", (func.__name__, args, kwargs)) | ||
return cached_response.value | ||
|
||
LOGGER.info("[ANALYTICS]: Cache miss for key: (%s)", (func.__name__, args, kwargs)) | ||
result = func(self, *args, **kwargs) | ||
cache.set(cache_key, result, timeout=timeout) | ||
return result | ||
return wrapper | ||
return inner_decorator |