summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2019-03-15 21:19:00 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2019-06-17 13:21:27 +0200
commit33860f86e6ec71435df7116746aae843a28fa14e (patch)
treeeea74693622e9a1f7770e2712d9ca974fe97f94a /ishtar_common/models.py
parentf29f108e4983b35ec24f70b1956d1ad00073feee (diff)
downloadIshtar-33860f86e6ec71435df7116746aae843a28fa14e.tar.bz2
Ishtar-33860f86e6ec71435df7116746aae843a28fa14e.zip
Celery: manage stats generation on sheets
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r--ishtar_common/models.py68
1 files changed, 61 insertions, 7 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index b535d9bf7..bacfd2147 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -83,7 +83,7 @@ from ishtar_common.models_imports import ImporterModel, ImporterType, \
from ishtar_common.templatetags.link_to_window import simple_link_to_window
from ishtar_common.utils import get_cache, disable_for_loaddata, create_slug, \
get_all_field_names, merge_tsvectors, cached_label_changed, \
- generate_relation_graph, max_size_help
+ generate_relation_graph, max_size_help, task
__all__ = [
'ImporterModel', 'ImporterType', 'ImporterDefault', 'ImporterDefaultValues',
@@ -2769,6 +2769,57 @@ class UserDashboard:
.order_by('person__person_types')
+class StatsCache(models.Model):
+ model = models.CharField(_("Model name"), max_length=200)
+ model_pk = models.IntegerField(_("Associated primary key"))
+ values = JSONField(default={}, blank=True)
+ updated = models.DateTimeField(default=datetime.datetime.now)
+ update_requested = models.DateTimeField(blank=True, null=True)
+
+ class Meta:
+ verbose_name = _("Cache for stats")
+ verbose_name_plural = _("Caches for stats")
+
+
+def update_stats(statscache, item, funcname):
+ if not settings.USE_BACKGROUND_TASK:
+ statscache.values = getattr(item, funcname)()
+ statscache.updated = datetime.datetime.now()
+ statscache.save()
+ return statscache.values
+
+ now = datetime.datetime.now()
+ if statscache.update_requested and (
+ statscache.update_requested + datetime.timedelta(hours=12) > now):
+ return statscache.values
+ app_name = item._meta.app_label
+ model_name = item._meta.model_name
+ statscache.update_requested = now.isoformat()
+ statscache.save()
+ _update_stats.delay(app_name, model_name, item.pk, funcname)
+ return statscache.values
+
+
+@task()
+def _update_stats(app, model, model_pk, funcname):
+ model_name = app + "." + model
+ sc, __ = StatsCache.objects.get_or_create(
+ model=model_name, model_pk=model_pk
+ )
+ model = apps.get_model(app, model)
+ try:
+ item = model.objects.get(pk=model_pk)
+ except model.DoesNotExist:
+ return
+ sc.values = getattr(item, funcname)()
+ sc.update_requested = None
+ sc.updated = datetime.datetime.now()
+ sc.save()
+ sc, __ = StatsCache.objects.get_or_create(
+ model=model_name, model_pk=model_pk
+ )
+
+
class DashboardFormItem(object):
"""
Provide methods to manage statistics
@@ -2776,12 +2827,15 @@ class DashboardFormItem(object):
def _get_or_set_stats(self, funcname, update,
timeout=settings.CACHE_TIMEOUT):
- key, val = get_cache(self.__class__, [funcname, self.pk])
- if not update and val is not None:
- return val
- val = getattr(self, funcname)()
- cache.set(key, val, timeout)
- return val
+ model_name = self._meta.app_label + "." + self._meta.model_name
+ sc, __ = StatsCache.objects.get_or_create(
+ model=model_name, model_pk=self.pk
+ )
+ now = datetime.datetime.now()
+ if sc.values and (
+ sc.updated + datetime.timedelta(seconds=timeout)) > now:
+ return sc.values
+ return update_stats(sc, self, funcname)
@classmethod
def get_periods(cls, slice='month', fltr={}, date_source='creation'):