refactor(recorder): Don't record cache activity

This commit is contained in:
Aditya Hase 2018-12-25 16:30:03 +05:30
parent 054e34f00e
commit 3f9bba02f7
3 changed files with 0 additions and 103 deletions

View file

@ -18,25 +18,6 @@
</div>
</div>
</div>
<div id="accordion-cache">
<div v-for="call in cache" :key="call.index" class="card">
<div class="card-header" :id="'heading-cache-' + call.index ">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" :data-target="'#collapse-cache-' + call.index ">
{{ call.call }}
{{ call.time.total }}
</button>
</h5>
</div>
<div :id="'collapse-cache-' + call.index " class="collapse" data-parent="#accordion-cache">
<div class="card-body">
<div><pre>{{ call.stack }}</pre></div>
<div><pre>{{ call.call }}</pre></div>
</div>
</div>
</div>
</div>
</div>
</template>
@ -56,7 +37,6 @@ export default {
uuid: this.$route.param
}
}).then( r => {
this.cache = r.message.cache
this.calls = r.message.calls
})
},

View file

@ -15,94 +15,17 @@ def recorder_start():
# Now is a good time
# If uuid is not set then RecorderMiddleware isn't active
if "uuid" in frappe.request.environ:
wrap_cache()
frappe.db.sql = recorder(frappe.db.sql)
def recorder_stop():
# Recorded calls need to be stored in cache
# This looks like a terribe syntax, Because it actually is
if "uuid" in frappe.request.environ:
persist_cache()
persist(frappe.db.sql)
def time_ms():
return time.time() * 1000
def wrap_cache():
def cache_recorder(function):
def wrapper(*args, **kwargs):
start_time_ms = time_ms()
result = function(*args, **kwargs)
end_time_ms = time_ms()
# Some elementary analysis shows that following lines are a little time consuming
# These can be made optional.
stack = "".join(traceback.format_stack())
data = {
"function": function.__name__,
#"args": args,
#"kwargs": kwargs,
# result is sometimes a nested dict, those can't be sometimes JSON serialized.
# pickle.dumps seems like a nice way to go., but JS can't understand pickle.
# Skip result for now
# "result": result,
"stack": stack,
# Exact redis query is not available for now
# Regenerate equivalent function call instead.
"call": "{}(*{},**{})".format(function.__name__, args, kwargs),
"time": {
"start": start_time_ms,
"end": end_time_ms,
"total": end_time_ms - start_time_ms,
},
}
wrapper.calls.append(data)
return result
wrapper.calls = list()
return wrapper
# frappe.cache() will provide an instance of RedisWrapper
# Selected methods of this class are used to do cache operations
# Recording activity of these methods will give a nice picture of cache activity
# cache_methods lists all interesting cache methods
# Override these methods with the use of wrapper function
# that records each call along with some suplimentary data
redis_server = frappe.cache()
cache_methods = [
"set_value", "get_value",
"get_all", "get_keys",
"delete_keys", "delete_key", "delete_value",
"lpush", "rpush", "lpop", "llen", "lrange",
"hset", "hgetall", "hincrby", "hget", "hdel", "hdel_keys", "hkeys",
"sadd", "srem", "sismember", "spop", "srandmember", "smembers",
"zincrby", "zrange"
]
# cache_methods will be needed again while storing recorded calls in cache
# Store cache_methods list in cache_methods attribute of wrap_cache
wrap_cache.cache_methods = cache_methods
for method in cache_methods:
# For now assume that all these methods exist on RedisWrapper instance
original = getattr(redis_server, method)
modified = cache_recorder(original)
setattr(redis_server, method, modified)
def persist_cache():
redis_server = frappe.cache()
cache_methods = wrap_cache.cache_methods
calls = []
uuid = frappe.request.environ["uuid"]
for method in cache_methods:
# Assumes that the method exists on RedisWrapper instance
# and function.calls also exists
function = getattr(redis_server, method)
calls.extend(function.calls)
# Record all calls in cache
frappe.cache().set("recorder-calls-cache-{}".format(uuid), dumps(calls))
def recorder(function):
def wrapper(*args, **kwargs):

View file

@ -32,13 +32,7 @@ def get_request_data(uuid):
for index, call in enumerate(calls):
call["index"] = index
cache = frappe.cache().get("recorder-calls-cache-{}".format(uuid))
cache = json.loads(cache.decode())
for index, call in enumerate(cache):
call["index"] = index
return {
"cache": cache,
"calls": calls,
}