69 lines
2.3 KiB
Python
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 ''
|