summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
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
commit296ee1376450adf58a040a9da816a100fa5d2ec9 (patch)
treebf7d12d69c5c3b8670f28a58e524200db008e8a0 /ishtar_common
parentc8a27a7f986adb1e3d0eb911acffa02d030cc85f (diff)
downloadIshtar-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.py23
-rw-r--r--ishtar_common/models_common.py54
-rw-r--r--ishtar_common/utils.py49
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