diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-03-18 00:13:45 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-06-17 13:21:27 +0200 |
commit | 198d988f5b22fe15c5ebf00a6c1f2fd1fcfe714d (patch) | |
tree | 6b76c894c6f5137f0e3cfdeb4d45afa7b5b72bcb | |
parent | 5870518f64a3a3961e30163e6ada557abe64e3e0 (diff) | |
download | Ishtar-198d988f5b22fe15c5ebf00a6c1f2fd1fcfe714d.tar.bz2 Ishtar-198d988f5b22fe15c5ebf00a6c1f2fd1fcfe714d.zip |
Improve performance of cached_label and geo post_save
-rw-r--r-- | archaeological_warehouse/models.py | 23 | ||||
-rw-r--r-- | example_project/settings.py | 1 | ||||
-rw-r--r-- | ishtar_common/models.py | 5 | ||||
-rw-r--r-- | ishtar_common/utils.py | 41 |
4 files changed, 53 insertions, 17 deletions
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 15263fd88..756052f64 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -34,7 +34,7 @@ from ishtar_common.models import Document, GeneralType, get_external_id, \ DashboardFormItem, ShortMenuItem, \ document_attached_changed, SearchAltName, DynamicRequest, GeoItem, \ QRCodeItem, SearchVectorConfig, DocumentItem -from ishtar_common.utils import cached_label_changed, post_save_geo +from ishtar_common.utils import cached_label_changed, post_save_geo, task class WarehouseType(GeneralType): @@ -250,19 +250,34 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem, def save(self, *args, **kwargs): self.update_search_vector() super(Warehouse, self).save(*args, **kwargs) - for container in self.containers.all(): - cached_label_changed(Container, instance=container) self.skip_history_when_saving = True if not self.external_id or self.auto_external_id: external_id = get_external_id('warehouse_external_id', self) if external_id != self.external_id: - updated = True self.auto_external_id = True self.external_id = external_id self._cached_label_checked = False self.save() return + if not settings.USE_BACKGROUND_TASK: + update_containers(self) + else: + update_containers.delay(self.pk) + + +@task() +def update_containers(warehouse): + if not settings.USE_BACKGROUND_TASK: + for container in warehouse.containers.all(): + cached_label_changed(Container, instance=container) + return + try: + warehouse = Warehouse.objects.get(pk=warehouse) + except Warehouse.DoesNotExist: + return + for container in warehouse.containers.all(): + cached_label_changed(Container, instance=container) m2m_changed.connect(document_attached_changed, diff --git a/example_project/settings.py b/example_project/settings.py index bf2b26c31..f53176622 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -19,6 +19,7 @@ if "test" in sys.argv: IMAGE_MAX_SIZE = (1280, 960) # put None if no resizing THUMB_MAX_SIZE = (600, 600) +CACHE_TASK_TIMEOUT = 4 CACHE_SMALLTIMEOUT = 60 CACHE_TIMEOUT = 3600 CACHE_BACKEND = 'memcached://127.0.0.1:11211/' diff --git a/ishtar_common/models.py b/ishtar_common/models.py index bacfd2147..e07dbf930 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -1573,9 +1573,8 @@ class FullSearch(models.Model): new_search_vector = merge_tsvectors(search_vectors) changed = old_search != new_search_vector if save and changed: - self.search_vector = new_search_vector - self.skip_history_when_saving = True - self.save() + self.__class__.objects.filter(pk=self.pk).update( + search_vector=new_search_vector) elif not save: return new_search_vector return changed diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 3d9cfc13f..828a03da3 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -364,14 +364,17 @@ def cached_label_changed(sender, **kwargs): if not kwargs.get('instance'): return instance = kwargs.get('instance') - force_update = kwargs.get('force_update', False) if hasattr(instance, 'test_obj'): instance.test_obj.reached(sender, **kwargs) - if not force_update and hasattr(instance, '_cached_label_checked') \ - and instance._cached_label_checked: + cache_key, value = get_cache( + sender, ["cached_label_changed", kwargs['instance'].pk] + ) + if value: # multiple request too quick return + cache.set(cache_key, True, settings.CACHE_TASK_TIMEOUT) + if not settings.USE_BACKGROUND_TASK: return _cached_label_changed(sender, **kwargs) @@ -389,6 +392,10 @@ def _cached_label_changed(sender, **kwargs): EXTRA_KWARGS_TRIGGER) if not instance: return + force_update = kwargs.get('force_update', False) + + if not force_update and getattr(instance, '_cached_label_checked', False): + return force_update = kwargs.get('force_update', False) @@ -399,17 +406,16 @@ def _cached_label_changed(sender, **kwargs): cached_labels = ['cached_label'] if hasattr(sender, 'CACHED_LABELS'): cached_labels = sender.CACHED_LABELS - changed = False + changed = [] for cached_label in cached_labels: lbl = getattr(instance, '_generate_' + cached_label)() if lbl != getattr(instance, cached_label): - setattr(instance, cached_label, lbl) - changed = True + changed.append((cached_label, lbl)) if changed: instance._search_updated = False if hasattr(instance, '_cascade_change') and instance._cascade_change: instance.skip_history_when_saving = True - instance.save() + sender.objects.filter(pk=instance.pk).update(**dict(changed)) updated = False if force_update or hasattr(instance, 'update_search_vector'): updated = instance.update_search_vector() @@ -421,6 +427,10 @@ def _cached_label_changed(sender, **kwargs): if hasattr(instance, 'test_obj'): item.test_obj = instance.test_obj cached_label_changed(item.__class__, instance=item) + cache_key, __ = get_cache( + sender, ["cached_label_changed", instance.pk] + ) + cache.set(cache_key, None, settings.CACHE_TASK_TIMEOUT) def regenerate_all_cached_labels(model): @@ -570,9 +580,13 @@ def post_save_geo(sender, **kwargs): """ Convert raw x, y, z point to real geo field """ - if not kwargs.get('instance') or getattr(kwargs['instance'], - '_post_saved_geo', False): + if not kwargs.get('instance'): return + cache_key, value = get_cache( + sender, ["post_save_geo", kwargs['instance'].pk]) + if value: # multiple request too quick + return + cache.set(cache_key, True, settings.CACHE_TASK_TIMEOUT) if not settings.USE_BACKGROUND_TASK: return _post_save_geo(sender, **kwargs) @@ -603,6 +617,9 @@ def _post_save_geo(sender, **kwargs): or "Warehouse" in kls_name): return + if getattr(instance, '_post_saved_geo', False): + return + # print(sender, "post_save_geo") current_source = "default" @@ -621,7 +638,6 @@ def _post_save_geo(sender, **kwargs): # should be a db source instance.multi_polygon_source = 'P' instance.multi_polygon_source_item = current_source - modified = True elif instance.multi_polygon_source != 'P': precise_poly = instance.get_precise_polygons() if precise_poly: @@ -755,7 +771,12 @@ def _post_save_geo(sender, **kwargs): if modified: instance.skip_history_when_saving = True instance._post_saved_geo = True + instance._cached_label_checked = False instance.save() + cache_key, __ = get_cache( + sender, ["post_save_geo", instance.pk] + ) + cache.set(cache_key, None, settings.CACHE_TASK_TIMEOUT) return |