2014-12-08 22:00:08 +01:00
|
|
|
# coding: utf-8
|
|
|
|
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
from collections import defaultdict
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from debug_toolbar.panels import Panel
|
2015-11-27 16:03:27 +01:00
|
|
|
from django.apps import apps
|
2014-12-08 22:00:08 +01:00
|
|
|
from django.conf import settings
|
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from django.utils.timesince import timesince
|
|
|
|
|
2016-11-22 15:09:39 +01:00
|
|
|
from .cache import cachalot_caches
|
2017-06-04 18:37:39 +02:00
|
|
|
from .settings import cachalot_settings
|
2014-12-08 22:00:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
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):
|
2015-11-27 16:03:27 +01:00
|
|
|
models = apps.get_models()
|
2014-12-08 22:00:08 +01:00
|
|
|
data = defaultdict(list)
|
2016-11-22 15:09:39 +01:00
|
|
|
cache = cachalot_caches.get_cache()
|
2014-12-08 22:00:08 +01:00
|
|
|
for db_alias in settings.DATABASES:
|
2017-06-04 18:37:39 +02:00
|
|
|
get_table_cache_key = cachalot_settings.CACHALOT_TABLE_KEYGEN
|
|
|
|
model_cache_keys = {
|
|
|
|
get_table_cache_key(db_alias, model._meta.db_table): model
|
|
|
|
for model in models}
|
2014-12-08 22:00:08 +01:00
|
|
|
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 \
|
2014-12-09 03:17:09 +01:00
|
|
|
or invalidation > self.last_invalidation:
|
2014-12-08 22:00:08 +01:00
|
|
|
self.last_invalidation = invalidation
|
|
|
|
data[db_alias].sort(key=lambda row: row[2], reverse=True)
|
|
|
|
self.record_stats({'invalidations_per_db': data.items()})
|
|
|
|
|
2014-12-09 03:17:09 +01:00
|
|
|
@property
|
2014-12-08 22:00:08 +01:00
|
|
|
def nav_subtitle(self):
|
|
|
|
if self.enabled and self.last_invalidation is not None:
|
|
|
|
return (_('Last invalidation: %s')
|
|
|
|
% timesince(self.last_invalidation))
|
|
|
|
return ''
|