debian-django-cachalot/cachalot/panels.py

69 lines
2.3 KiB
Python

# coding: utf-8
from __future__ import unicode_literals
from collections import defaultdict
from datetime import datetime
from debug_toolbar.panels import Panel
from django.apps import apps
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils.timesince import timesince
from .cache import cachalot_caches
from .utils import _get_table_cache_key
class CachalotPanel(Panel):
title = 'Cachalot'
template = 'cachalot/panel.html'
def __init__(self, *args, **kwargs):
self.last_invalidation = None
super(CachalotPanel, self).__init__(*args, **kwargs)
@property
def enabled(self):
enabled = super(CachalotPanel, self).enabled
if enabled:
self.enable_instrumentation()
else:
self.disable_instrumentation()
return enabled
def enable_instrumentation(self):
settings.CACHALOT_ENABLED = True
def disable_instrumentation(self):
settings.CACHALOT_ENABLED = False
def process_response(self, request, response):
self.collect_invalidations()
def collect_invalidations(self):
models = apps.get_models()
data = defaultdict(list)
cache = cachalot_caches.get_cache()
for db_alias in settings.DATABASES:
model_cache_keys = dict(
[(_get_table_cache_key(db_alias, model._meta.db_table), model)
for model in models])
for cache_key, timestamp in cache.get_many(
model_cache_keys.keys()).items():
invalidation = datetime.fromtimestamp(timestamp)
model = model_cache_keys[cache_key]
data[db_alias].append(
(model._meta.app_label, model.__name__, invalidation))
if self.last_invalidation is None \
or invalidation > self.last_invalidation:
self.last_invalidation = invalidation
data[db_alias].sort(key=lambda row: row[2], reverse=True)
self.record_stats({'invalidations_per_db': data.items()})
@property
def nav_subtitle(self):
if self.enabled and self.last_invalidation is not None:
return (_('Last invalidation: %s')
% timesince(self.last_invalidation))
return ''