Skip to content

Commit

Permalink
Update debug panel so signals are always sent when available
Browse files Browse the repository at this point in the history
Addresses #4 and #7
  • Loading branch information
rlskoeser committed Jul 26, 2016
1 parent 96cfdb9 commit fbf1950
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 33 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ any necessary information about installation or upgrade notes.
* Removed ``overwrite`` option from :meth:`eulexistdb.ExistDB.load`
(no longer applicable under the REST API, and misleading)
`#9 <https://github.com/emory-libraries/eulexistdb/issues/9>`_
* Improved django-debug-toolbar integration. Addresses
`#7 <https://github.com/emory-libraries/eulexistdb/issues/7>`_
and `#8 <https://github.com/emory-libraries/eulexistdb/issues/8>`_.

0.20
----
Expand Down
23 changes: 22 additions & 1 deletion eulexistdb/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,17 @@
import logging
import requests
import socket
import time
from urllib import unquote_plus, splittype
import urlparse
import warnings
import xmlrpclib

try:
from django.dispatch import Signal
except ImportError:
Signal = None

from . import patch
from eulxml import xmlmap
from eulexistdb.exceptions import ExistDBException, ExistDBTimeout
Expand All @@ -114,6 +120,7 @@

EXISTDB_NAMESPACE = 'http://exist.sourceforge.net/NS/exist'


def _wrap_xmlrpc_fault(f):
@wraps(f)
def wrapper(*args, **kwargs):
Expand All @@ -129,6 +136,12 @@ def wrapper(*args, **kwargs):
# error: [Errno 104] Connection reset by peer
return wrapper

xquery_called = None
if Signal is not None:
xquery_called = Signal(providing_args=[
"time_taken", "name", "return_value", "args", "kwargs"])



class ExistDB(object):
"""Connect to an eXist database, and manipulate and query it.
Expand Down Expand Up @@ -484,10 +497,18 @@ def query(self, xquery=None, start=1, how_many=10, cache=False, session=None,
else:
debug_query = ''
logger.debug('query %s%s' % (opts, debug_query))

start = time.time()
response = self.session.get(self.restapi_path(''), params=params,
stream=False, **self.session_opts)

if xquery_called is not None:
args = {'xquery': xquery, 'start': start, 'how_many': how_many,
'cache': cache, 'session': session, 'release': release,
'result_type': result_type}
xquery_called.send(
sender=self.__class__, time_taken=time.time() - start,
name='query', return_value=response, args=[], kwargs=args)

if response.status_code == requests.codes.ok:
# successful release doesn't return any content
if release is not None:
Expand Down
41 changes: 10 additions & 31 deletions eulexistdb/debug_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,6 @@
# implementation based on django-debug-toolbar cache panel


xquery_called = Signal(providing_args=[
"time_taken", "name", "return_value", "args", "kwargs"])


class ExistDBTracker(db.ExistDB):
# subclass ExistDB in order to track query calls

def query(self, *args, **kwargs):
start = time.time()
value = super(ExistDBTracker, self).query(*args, **kwargs)
total_time = time.time() - start
xquery_called.send(sender=self.__class__, time_taken=total_time,
name='query', return_value=value,
args=args, kwargs=kwargs)
return value


class ExistDBPanel(Panel):

name = 'ExistDB'
Expand All @@ -51,7 +34,7 @@ def __init__(self, *args, **kwargs):
self.total_time = 0
self.queries = []

xquery_called.connect(self._store_xquery_info)
db.xquery_called.connect(self._store_xquery_info)

def _store_xquery_info(self, sender, name=None, time_taken=0,
return_value=None, args=None, kwargs=None,
Expand All @@ -65,6 +48,11 @@ def _store_xquery_info(self, sender, name=None, time_taken=0,
if hasattr(return_value, 'serialize'):
return_value = return_value.serialize()

# remove empty values from kwargs, to simplify display
for k, val in list(kwargs.iteritems()):
if val is None:
del args[k]

time_taken *= 1000
self.total_time += time_taken
self.queries.append({
Expand All @@ -85,19 +73,10 @@ def title(self):
return self.name

def nav_subtitle(self):
return "%(xqueries)d queries in %(time).2fms" % \
{'xqueries': len(self.queries), 'time': self.total_time}

def enable_instrumentation(self):
# patch tracking existdb subclass in for the real one
db.RealExistDB = db.ExistDB
eulexistdb.db.ExistDB = ExistDBTracker
# also patch into the manager module (already imported)
eulexistdb.manager.ExistDB = db.ExistDB

def disable_instrumentation(self):
db.ExistDB = db.RealExistDB
eulexistdb.manager.ExistDB = db.ExistDB
return "%(xqueries)d quer%(plural)s in %(time).2fms" % \
{'xqueries': len(self.queries),
'plural': 'y' if (len(self.queries) == 1) else 'ies',
'time': self.total_time}

def generate_stats(self, request, response):
# statistics for display in the template
Expand Down
4 changes: 3 additions & 1 deletion eulexistdb/templates/eulexistdb/debug_panel.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load i18n %}{% load cycle from debug_toolbar_compat %}
{% load i18n %}
<h4>{% trans "Summary" %}</h4>
<table>
<thead>
Expand Down Expand Up @@ -35,7 +35,9 @@ <h4>{% trans "Queries" %}</h4>
<td>{{ query.time|floatformat:"4" }}</td>
<td><pre>{% firstof query.args.0 query.kwargs.xquery %}</pre></td>
<td>{% for arg, opt in query.kwargs.iteritems %}
{% if arg = 'xquery' %} {# skip - already displayed #} {% else %}
{{ arg }}: {{ opt }}{% if not forloop.last %}<br/>{% endif %}
{% endif %}
{% endfor %}
</td>
</tr>
Expand Down

0 comments on commit fbf1950

Please sign in to comment.