# HG changeset patch # User Laurent Peuch # Date 1568260750 -7200 # Node ID 7d2c61d40fe9ab107fc10111c46b785e8304e17a # Parent d506613674011d6ea61b48891744abbc8b18d9c6 [debug-toolbar] add registry decisions debug panel Closes #17219866 diff -r d50661367401 -r 7d2c61d40fe9 cubicweb/cwvreg.py --- a/cubicweb/cwvreg.py Wed Nov 20 20:46:45 2019 +0100 +++ b/cubicweb/cwvreg.py Thu Sep 12 05:59:10 2019 +0200 @@ -33,6 +33,7 @@ from yams.constraints import BASE_CONVERTERS from cubicweb import _ +from cubicweb.debug import emit_to_debug_channel from cubicweb import (CW_SOFTWARE_ROOT, ETYPE_NAME_MAP, CW_EVENT_MANAGER, onevent, Binary, UnknownProperty, UnknownEid) from cubicweb.predicates import appobject_selectable, _reset_is_instance_cache @@ -72,6 +73,16 @@ super(CWRegistry, self).__init__(True) self.vreg = vreg + def _select_best(self, objects, *args, **kwargs): + """ + Overwrite version of Registry._select_best to emit debug information. + """ + def emit_registry_debug_information(debug_registry_select_best): + emit_to_debug_channel("registry_decisions", debug_registry_select_best) + + kwargs["debug_callback"] = emit_registry_debug_information + return super()._select_best(objects, *args, **kwargs) + @property def schema(self): """The :py:class:`cubicweb.schema.CubicWebSchema` diff -r d50661367401 -r 7d2c61d40fe9 cubicweb/debug.py --- a/cubicweb/debug.py Wed Nov 20 20:46:45 2019 +0100 +++ b/cubicweb/debug.py Thu Sep 12 05:59:10 2019 +0200 @@ -26,6 +26,7 @@ "rql": [], "sql": [], "vreg": [], + "registry_decisions": [], } diff -r d50661367401 -r 7d2c61d40fe9 cubicweb/pyramid/debug_toolbar_templates/registry_decisions.dbtmako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/pyramid/debug_toolbar_templates/registry_decisions.dbtmako Thu Sep 12 05:59:10 2019 +0200 @@ -0,0 +1,65 @@ +<%def name="render_object(obj)"> +% if hasattr(obj, "__name__"): + ${obj.__module__}.${obj.__name__} +% else: + ${obj} +% endif + + + + + + + + +% for registry_decision in registry_decisions: + + + + + + + + + + +% endfor +
ResultDecision
${repr(registry_decision["key"])} -> ${render_object(registry_decision["winner"])}
+

End score: ${registry_decision["end_score"]}

+
args: ${highlight(registry_decision["args"], "html") | n}
+
kwargs: +
    + % for key, value in registry_decision["kwargs"].items(): +
  • ${repr(key)}: ${repr(value)}
  • + % endfor +
+
+
+
    + % for obj in registry_decision["all_objects"]: +
  • + ${obj["score"]}: ${render_object(obj["object"])} +
  • + % endfor +
+
+ diff -r d50661367401 -r 7d2c61d40fe9 cubicweb/pyramid/debugtoolbar_panels.py --- a/cubicweb/pyramid/debugtoolbar_panels.py Wed Nov 20 20:46:45 2019 +0100 +++ b/cubicweb/pyramid/debugtoolbar_panels.py Thu Sep 12 05:59:10 2019 +0200 @@ -54,6 +54,59 @@ unsubscribe_to_debug_channel("controller", self.collect_controller) +class RegistryDecisionsDebugPanel(DebugPanel): + """ + CubicWeb registry decisions debug panel + """ + + name = 'RegistryDecisions' + title = 'Registry Decisions' + nav_title = 'Registry Decisions' + + has_content = True + template = 'cubicweb.pyramid:debug_toolbar_templates/registry_decisions.dbtmako' + + def __init__(self, request): + # clear on every new response + self.data = { + 'registry_decisions': [], + 'vreg': None, + 'highlight': highlight_html, + 'generate_css': generate_css, + } + + subscribe_to_debug_channel("vreg", self.collect_vreg) + subscribe_to_debug_channel("registry_decisions", self.collect_registry_decisions) + + def collect_vreg(self, message): + self.data["vreg"] = message["vreg"] + + def collect_registry_decisions(self, decision): + # decision = { + # "all_objects": [], + # "end_score": int, + # "winners": [], + # "registry": obj, + # "args": args, + # "kwargs": kwargs, + # } + decision["key"] = None + self.data["registry_decisions"].append(decision) + + def link_registry_to_their_key(self): + if self.data["vreg"]: + # use "id" here to be hashable + registry_to_key = {id(registry): key for key, registry in self.data["vreg"].items()} + for decision in self.data["registry_decisions"]: + decision["key"] = registry_to_key.get(id(decision["self"])) + + def process_response(self, response): + unsubscribe_to_debug_channel("registry_decisions", self.collect_registry_decisions) + unsubscribe_to_debug_channel("vreg", self.collect_vreg) + + self.link_registry_to_their_key() + + class RegistryDebugPanel(DebugPanel): """ CubicWeb registry content and decisions debug panel @@ -190,6 +243,7 @@ def includeme(config): config.add_debugtoolbar_panel(CubicWebDebugPanel) + config.add_debugtoolbar_panel(RegistryDecisionsDebugPanel) config.add_debugtoolbar_panel(RegistryDebugPanel) config.add_debugtoolbar_panel(RQLDebugPanel) config.add_debugtoolbar_panel(SQLDebugPanel)