diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-09-12 12:39:40 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-09-13 13:34:27 +0200 |
commit | 296ee1376450adf58a040a9da816a100fa5d2ec9 (patch) | |
tree | bf7d12d69c5c3b8670f28a58e524200db008e8a0 /ishtar_common | |
parent | c8a27a7f986adb1e3d0eb911acffa02d030cc85f (diff) | |
download | Ishtar-296ee1376450adf58a040a9da816a100fa5d2ec9.tar.bz2 Ishtar-296ee1376450adf58a040a9da816a100fa5d2ec9.zip |
⚡️ improve performance - external ID: prevent double save - user UPDATE query instead of save - remove dead code "BulkUpdatedItem"
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/models.py | 23 | ||||
-rw-r--r-- | ishtar_common/models_common.py | 54 | ||||
-rw-r--r-- | ishtar_common/utils.py | 49 |
3 files changed, 59 insertions, 67 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 394bd5382..48ed55e77 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -577,29 +577,6 @@ class ImageModel(models.Model, ImageContainerModel): return "{}-thumb.{}".format(".".join(splited[:-1]), splited[-1]) -class BulkUpdatedItem(object): - @classmethod - def bulk_recursion(cls, transaction_id, extra_args): - """ - Prevent infinite recursion. Should not happen but wrong manipulation - in the database or messy imports can generate circular relations - - :param transaction_id: current transaction ID (unix time) - if null - a transaction ID is generated - :param extra_args: arguments dealing with - :return: (transaction ID, is a recursion) - """ - # TODO: no more bulk update - should be removed - if not transaction_id: - transaction_id = str(time.time()) - args = ["cached_label_bulk_update", transaction_id] + extra_args - key, val = get_cache(cls, args) - if val: - return transaction_id, True - cache.set(key, 1, settings.CACHE_SMALLTIMEOUT) - return transaction_id, False - - class RelationItem(models.Model): """ Items with relation between them diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 0b34400a1..98dbb047b 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -1615,20 +1615,39 @@ class BaseHistorizedItem( def duplicate(self, user=None, data=None): return duplicate_item(self, user, data) - def update_external_id(self, save=False): - if not self.EXTERNAL_ID_KEY or ( - self.external_id and not getattr(self, "auto_external_id", False) - ): + def update_external_id(self, save=False, no_set=False): + if not hasattr(self, "external_id"): + return + if self.external_id and not getattr(self, "auto_external_id", False): return - external_id = get_generated_id(self.EXTERNAL_ID_KEY, self) + external_id_key = self.EXTERNAL_ID_KEY or ( + hasattr(self, "SLUG") and (self.SLUG + "_external_id") + ) + if not external_id_key: + return + external_id = get_generated_id(external_id_key, self) if external_id == self.external_id: return - self.auto_external_id = True - self.external_id = external_id + if no_set: + return external_id + try: + self.auto_external_id = True + except AttributeError: + pass + try: + self.external_id = external_id + except AttributeError: + return self._cached_label_checked = False if save: - self.skip_history_when_saving = True - self.save() + if self.pk: + self.__class__.objects.filter(pk=self.pk).update( + auto_external_id=True, + external_id=external_id + ) + else: + self.skip_history_when_saving = True + self.save() return external_id def get_last_history_date(self): @@ -4524,22 +4543,25 @@ class CompleteIdentifierItem(models.Model, ImageContainerModel): def regenerate_all_ids(self, save=True): if getattr(self, "_prevent_loop", False): - return - modified = False + return {} + updated = {} custom_index = self.generate_custom_index() if custom_index != self.custom_index: - modified = True self.custom_index = custom_index + updated["custom_index"] = custom_index complete_id = self.generate_complete_identifier() if complete_id and complete_id != self.complete_identifier: - modified = True self.complete_identifier = complete_id - if modified: + updated["complete_identifier"] = complete_id + if updated: self._prevent_loop = True self.skip_history_when_saving = True if save: - self.save() - return modified + if self.pk: + self.__class__.objects.filter(pk=self.pk).update(**updated) + else: + self.save() + return updated class SearchVectorConfig: diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 40fb4db04..3249bb20e 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -871,14 +871,8 @@ def cached_label_changed(sender, **kwargs): queue = getattr(instance, "_queue", settings.CELERY_DEFAULT_QUEUE) if hasattr(instance, "external_id") and hasattr(instance, "auto_external_id") \ and hasattr(instance, "SLUG") and not getattr(instance, "_external_id_checked", None): - changed = load_task(_external_id_changed, "external_id_changed", None, sender, - queue=queue, **kwargs) - if changed and ( - not settings.USE_BACKGROUND_TASK - or not instance.pk - or not sender.objects.filter(pk=instance.pk).count() - ): # cached_label_changed re-triggered - return + load_task(_external_id_changed, "external_id_changed", None, sender, + queue=queue, **kwargs) force_update = kwargs.get("force_update", False) if getattr(instance, "need_update", False): @@ -943,10 +937,6 @@ def _cached_label_changed(sender, **kwargs): updated = False if force_update or hasattr(instance, "update_search_vector"): updated = instance.update_search_vector() - if hasattr(instance, "_cached_labels_bulk_update"): - # updated = instance._cached_labels_bulk_update() or updated - # disable now - pass if not updated and hasattr(instance, "_get_associated_cached_labels"): for item in instance._get_associated_cached_labels(): item._cascade_change = True @@ -955,7 +945,6 @@ def _cached_label_changed(sender, **kwargs): if instance.timestamp_label: item._timestamp = instance.timestamp_label 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) if cached_labels: @@ -999,26 +988,30 @@ def _external_id_changed(sender, **kwargs): if getattr(instance, "_external_id_checked", None): return instance._queue = kwargs.get("queue", settings.CELERY_DEFAULT_QUEUE) - updated = False + updated = {} if not instance.external_id or instance.auto_external_id: - external_id = get_generated_id(instance.SLUG + "_external_id", instance) - if external_id != instance.external_id: - try: - instance.auto_external_id = True - instance.external_id = external_id - updated = True - except AttributeError: - pass + if hasattr(instance, "update_external_id"): + external_id = instance.update_external_id(save=False, no_set=True) + else: + external_id = get_generated_id(instance.SLUG + "_external_id", instance) + + if external_id and external_id != instance.external_id: + updated = {"auto_external_id": True, "external_id": external_id} + instance.auto_external_id = True + instance.external_id = external_id if hasattr(instance, "regenerate_all_ids"): - updated |= instance.regenerate_all_ids(save=False) or False + updated.update(instance.regenerate_all_ids(save=False)) instance._external_id_checked = True if updated: - if settings.USE_BACKGROUND_TASK and hasattr(instance, "no_post_process"): - instance.no_post_process() + if instance.pk: + instance.__class__.objects.filter(pk=instance.pk).update(**updated) else: - instance._no_move = True - instance.skip_history_when_saving = True - instance.save() + if settings.USE_BACKGROUND_TASK and hasattr(instance, "no_post_process"): + instance.no_post_process() + else: + instance._no_move = True + instance.skip_history_when_saving = True + instance.save() return True |