Skip to content

Instantly share code, notes, and snippets.

@boxbeatsy
Last active November 22, 2020 19:07
Show Gist options
  • Save boxbeatsy/87bdbc8f997872c77856c4d8cc8638f4 to your computer and use it in GitHub Desktop.
Save boxbeatsy/87bdbc8f997872c77856c4d8cc8638f4 to your computer and use it in GitHub Desktop.
##TO BE PASTED AT THE TOP OF WSGI.PY
import cachalot.monkey_patch, pickle
from cachalot.monkey_patch import *
from cachalot.utils import (
_get_query_cache_key, _get_table_cache_keys, _get_tables_from_sql,
_invalidate_table, UncachableQuery, TUPLE_OR_LIST)
def patched_get_result_or_execute_query(execute_query_func, cache,
cache_key, table_cache_keys, model_name=None):
metric_prefix = cache.__class__.__name__
if 'Atomic' not in metric_prefix:
try:
if not cache.get('cachalot_tries'):
cache.set('cachalot_tries',1,90000)
else:
cache.incr('cachalot_tries',1)
if model_name:
if not cache.get(model_name+'cachalot_tries'):
cache.set(model_name+'cachalot_tries',1,90000)
else:
cache.incr(model_name+'cachalot_tries',1)
except:
print metric_prefix + 'failed cachalot metric incr'
data = cache.get_many(table_cache_keys + [cache_key])
new_table_cache_keys = set(table_cache_keys)
new_table_cache_keys.difference_update(data)
if new_table_cache_keys:
now = time()
cache.set_many({k: now for k in new_table_cache_keys}, None)
elif cache_key in data:
timestamp, result = data.pop(cache_key)
table_times = data.values()
if table_times and timestamp > max(table_times):
# print 'returning cached value'
if 'Atomic' not in metric_prefix:
try:
if not cache.get('cachalot_hit'):
cache.set('cachalot_hit',1,90000)
else:
cache.incr('cachalot_hit',1)
if model_name:
if not cache.get(model_name+'cachalot_hit'):
cache.set(model_name+'cachalot_hit',1,90000)
else:
cache.incr(model_name+'cachalot_hit',1)
except:
print metric_prefix + 'failed cachalot metric incr'
return result
# print 'running actual query'
result = execute_query_func()
if isinstance(result, Iterable) and result.__class__ not in TUPLE_OR_LIST:
result = list(result)
# print 'setting cache'
cache.set(cache_key, (time(), result), None)
if 'Atomic' not in metric_prefix and model_name:
try:
# if model_name == 'Availability':
# print str(pickle.dumps(result))
obj_size = len(pickle.dumps(result))
if obj_size < 1:
obj_size = 1
if not cache.get(model_name+'cachalot_size'):
cache.set(model_name+'cachalot_size',obj_size,90000)
else:
cache.incr(model_name+'cachalot_size',obj_size)
# print model_name+'cachalot_size'
except:
pass
return result
def patched_unset_raw_connection(original):
def inner(compiler, *args, **kwargs):
compiler.connection.raw = False
out = original(compiler, *args, **kwargs)
compiler.connection.raw = True
return out
return inner
def patched_patch_compiler(original):
@wraps(original)
@patched_unset_raw_connection
def inner(compiler, *args, **kwargs):
# print "model name:" +str(compiler.query.model.__name__)
execute_query_func = lambda: original(compiler, *args, **kwargs)
if not cachalot_settings.CACHALOT_ENABLED \
or isinstance(compiler, WRITE_COMPILERS):
return execute_query_func()
try:
cache_key = _get_query_cache_key(compiler)
table_cache_keys = _get_table_cache_keys(compiler)
except (EmptyResultSet, UncachableQuery):
return execute_query_func()
return patched_get_result_or_execute_query(
execute_query_func,
cachalot_caches.get_cache(db_alias=compiler.using),
cache_key, table_cache_keys, model_name=str(compiler.query.model.__name__))
return inner
cachalot.monkey_patch._unset_raw_connection = patched_unset_raw_connection
cachalot.monkey_patch._patch_compiler = patched_patch_compiler
cachalot.monkey_patch._get_result_or_execute_query = patched_get_result_or_execute_query
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment