summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2019-11-27 17:40:33 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2019-11-27 17:40:33 +0100
commitda3f424cebee78b30c1419e40ae5097caab8a888 (patch)
treec6e07b9206418b6a05e5e69e2a4022657feb1db3
parent13b56b597d2177813d9ccf434201f90bc80a8b11 (diff)
downloadIshtar-da3f424cebee78b30c1419e40ae5097caab8a888.tar.bz2
Ishtar-da3f424cebee78b30c1419e40ae5097caab8a888.zip
Background post save: wait for not commited object
-rw-r--r--ishtar_common/models.py33
-rw-r--r--ishtar_common/utils.py21
2 files changed, 34 insertions, 20 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index e7f0e9262..946e88703 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -2103,8 +2103,24 @@ class StatisticItem:
) # example: "Price", "Volume" - the number is a multiplier
+class CascasdeUpdate:
+ DOWN_MODEL_UPDATE = []
+
+ def cascade_update(self):
+ for down_model in self.DOWN_MODEL_UPDATE:
+ if not settings.USE_BACKGROUND_TASK:
+ rel = getattr(self, down_model)
+ if hasattr(rel.model, "need_update"):
+ rel.update(need_update=True)
+ continue
+ for item in getattr(self, down_model).all():
+ cached_label_changed(item.__class__, instance=item)
+ if hasattr(item, "point_2d"):
+ post_save_geo(item.__class__, instance=item)
+
+
class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
- JsonData, FixAssociated):
+ JsonData, FixAssociated, CascasdeUpdate):
"""
Historized item with external ID management.
All historized items are searchable and have a data json field.
@@ -2114,7 +2130,6 @@ class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
SHOW_URL = None
EXTERNAL_ID_KEY = ''
EXTERNAL_ID_DEPENDENCIES = []
- DOWN_MODEL_UPDATE = []
HISTORICAL_M2M = []
history_modifier = models.ForeignKey(
@@ -2151,18 +2166,6 @@ class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
class Meta:
abstract = True
- def cascade_update(self):
- for down_model in self.DOWN_MODEL_UPDATE:
- if not settings.USE_BACKGROUND_TASK:
- rel = getattr(self, down_model)
- if hasattr(rel.model, "need_update"):
- rel.update(need_update=True)
- continue
- for item in getattr(self, down_model).all():
- cached_label_changed(item.__class__, instance=item)
- if hasattr(item, "point_2d"):
- post_save_geo(item.__class__, instance=item)
-
@classmethod
def get_verbose_name(cls):
return cls._meta.verbose_name
@@ -4875,8 +4878,8 @@ post_delete.connect(post_save_cache, sender=AuthorType)
class Author(FullSearch):
- PARENT_SEARCH_VECTORS = ['person']
SLUG = "author"
+ PARENT_SEARCH_VECTORS = ['person']
uuid = models.UUIDField(default=uuid.uuid4)
person = models.ForeignKey(Person, verbose_name=_("Person"),
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 641fbd156..d22a89916 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -36,6 +36,7 @@ import six
import subprocess
import sys
import tempfile
+import time
import xmltodict
import zipfile
@@ -418,9 +419,18 @@ def deserialize_args_for_tasks(sender, kwargs, extra_kwargs=None):
if not isinstance(sender, (tuple, list)): # not task
return sender, kwargs["instance"]
sender = apps.get_model(*sender)
- try:
- instance = sender.objects.get(pk=kwargs['instance'])
- except sender.DoesNotExist:
+ instance = None
+ retried = 0
+ # object can be in cache of another thread but not yet commited
+ # waiting for it
+ while not instance and retried < 6:
+ if retried:
+ time.sleep(.5)
+ if sender.objects.filter(pk=kwargs['instance']).count():
+ instance = sender.objects.get(pk=kwargs['instance'])
+ else:
+ retried += 1
+ if not instance:
return sender, None # object is not here anymore
if extra_kwargs:
for kw in extra_kwargs:
@@ -456,7 +466,9 @@ def cached_label_changed(sender, **kwargs):
# return
# cache.set(cache_key, True, settings.CACHE_TASK_TIMEOUT)
- if not settings.USE_BACKGROUND_TASK:
+ if not settings.USE_BACKGROUND_TASK or not instance.pk \
+ or not sender.objects.filter(pk=instance.pk).count():
+ # no background task or not yet fully saved
return _cached_label_changed(sender, **kwargs)
if getattr(instance, "_cascade_change", False):
@@ -474,7 +486,6 @@ def _cached_label_changed(sender, **kwargs):
if not instance:
return
force_update = kwargs.get('force_update', False)
-
if hasattr(instance, "need_update") and instance.need_update:
force_update = True
instance.skip_history_when_saving = True