Open mikecodona opened 9 years ago
+1 to this. Mike - can you share the memoize function are you using?
Thanks, Dave
Hi Dave,
We our own version of memoize
which uses the django cache framework with the django.core.cache.backends.locmem.LocMemCache
backend which allows us to have a timeout, but django.utils.functional.memoize
will work and should give you somewhere to start if you need similar functionality.
Regards, Mike
We are doing the same:
Our cache function, which uses the Django cache backend but is generic for all kinds of functions:
from django.core.cache import cache as _djcache
from hashlib import sha1
def cache_results(seconds=900):
"""
Cache the result of a function call for the specified number of seconds,
using Django's caching mechanism.
Assumes that the function never returns None (as the cache returns None to
indicate a miss), and that the function's result only depends on its
parameters. Note that the ordering of parameters is important. e.g.
my_function(x = 1, y = 2), my_function(y = 2, x = 1), and my_function(1,2)
will each be cached separately.
Usage:
@cache_results(600)
def my_expensive_function(param1, param2, paarm3):
....
return expensive_result
"""
def do_cache(f):
def x(*args, **kwargs):
key = sha1(str(f.__module__) + str(f.__name__) + str(args) + str(kwargs)).hexdigest()
result = _djcache.get(key)
if result is None:
result = f(*args, **kwargs)
_djcache.set(key, result, seconds)
return result
return x
return do_cache
The monkey patch:
djmoney_rates.utils.get_rate = cache_results(100)(djmoney_rates.utils.get_rate)
djmoney_rates.utils.get_rate_source = cache_results(100)(djmoney_rates.utils.get_rate_source)
It's difficult to know exactly how this functionality should be integrated into django-money-rates.
Currently at least 2 database queries are performed for each currency conversion. This means that using django-money-rates for some tasks becomes infeasible, for example converting a large number of money amounts into a canonical currency so that they can be sorted according to true value.
With the current setup where rates are updated via a cronjob I don't think there would be a particular disadvantage in caching the results for 60s however possibly a more robust solution would be to use a configurable rates source backend which could be over-ridden to allow someone to add whatever caching logic they require.
At the moment I'm simply monkey patching the relevant functions:
Let me know if you have any thoughts or questions.
Thanks, Mike