diff options
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 |
commit | 33860f86e6ec71435df7116746aae843a28fa14e (patch) | |
tree | eea74693622e9a1f7770e2712d9ca974fe97f94a /ishtar_common/models.py | |
parent | f29f108e4983b35ec24f70b1956d1ad00073feee (diff) | |
download | Ishtar-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.py | 68 |
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'): |