Fix sporadic index instance node tree id warning.
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -206,18 +206,22 @@ class DocumentIndexingApp(MayanAppConfig):
|
|||||||
menu_tools.bind_links(links=(link_rebuild_index_instances,))
|
menu_tools.bind_links(links=(link_rebuild_index_instances,))
|
||||||
|
|
||||||
post_delete.connect(
|
post_delete.connect(
|
||||||
handler_delete_empty, dispatch_uid='handler_delete_empty',
|
dispatch_uid='document_indexing_handler_delete_empty',
|
||||||
|
receiver=handler_delete_empty,
|
||||||
sender=Document
|
sender=Document
|
||||||
)
|
)
|
||||||
pre_delete.connect(
|
pre_delete.connect(
|
||||||
handler_remove_document, dispatch_uid='handler_remove_document',
|
dispatch_uid='document_indexing_handler_remove_document',
|
||||||
|
receiver=handler_remove_document,
|
||||||
sender=Document
|
sender=Document
|
||||||
)
|
)
|
||||||
post_document_created.connect(
|
post_document_created.connect(
|
||||||
handler_index_document,
|
dispatch_uid='document_indexing_handler_index_document',
|
||||||
dispatch_uid='handler_index_document', sender=Document
|
receiver=handler_index_document,
|
||||||
|
sender=Document
|
||||||
)
|
)
|
||||||
post_initial_document_type.connect(
|
post_initial_document_type.connect(
|
||||||
create_default_document_index,
|
dispatch_uid='document_indexing_create_default_document_index',
|
||||||
dispatch_uid='create_default_document_index', sender=DocumentType
|
receiver=create_default_document_index,
|
||||||
|
sender=DocumentType
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -190,15 +190,16 @@ class IndexTemplateNode(MPTTModel):
|
|||||||
else:
|
else:
|
||||||
return self.expression
|
return self.expression
|
||||||
|
|
||||||
|
def get_lock_string(self):
|
||||||
|
return 'indexing:indexing_template_node_{}'.format(self.pk)
|
||||||
|
|
||||||
def index_document(self, document, acquire_lock=True, index_instance_node_parent=None):
|
def index_document(self, document, acquire_lock=True, index_instance_node_parent=None):
|
||||||
# Avoid another process indexing this same document for the same
|
# Avoid another process indexing this same document for the same
|
||||||
# template node. This prevents this template node's index instance
|
# template node. This prevents this template node's index instance
|
||||||
# nodes from being deleted while the template is evaluated and
|
# nodes from being deleted while the template is evaluated and
|
||||||
# documents added to it.
|
# documents added to it.
|
||||||
if acquire_lock:
|
if acquire_lock:
|
||||||
lock = locking_backend.acquire_lock(
|
lock = locking_backend.acquire_lock(self.get_lock_string())
|
||||||
'indexing:indexing_template_node_{}'.format(self.pk)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Start transaction after the lock in case the locking backend uses
|
# Start transaction after the lock in case the locking backend uses
|
||||||
# the database.
|
# the database.
|
||||||
@@ -212,11 +213,12 @@ class IndexTemplateNode(MPTTModel):
|
|||||||
'Removing document "%s" from all index instance nodes',
|
'Removing document "%s" from all index instance nodes',
|
||||||
document
|
document
|
||||||
)
|
)
|
||||||
for index_template_node in self.index_instance_nodes.all():
|
for index_instance_node in self.index_instance_nodes.all():
|
||||||
index_template_node.remove_document(
|
index_instance_node.remove_document(
|
||||||
document=document, acquire_lock=False
|
document=document, acquire_lock=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
if not self.parent:
|
if not self.parent:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'IndexTemplateNode; parent: creating empty root index '
|
'IndexTemplateNode; parent: creating empty root index '
|
||||||
@@ -263,6 +265,7 @@ class IndexTemplateNode(MPTTModel):
|
|||||||
parent=index_instance_node_parent,
|
parent=index_instance_node_parent,
|
||||||
value=result
|
value=result
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.link_documents:
|
if self.link_documents:
|
||||||
index_instance_node.documents.add(document)
|
index_instance_node.documents.add(document)
|
||||||
|
|
||||||
@@ -302,11 +305,6 @@ class IndexInstanceNode(MPTTModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
@property
|
|
||||||
def children(self):
|
|
||||||
# Convenience method for serializer
|
|
||||||
return self.get_children()
|
|
||||||
|
|
||||||
def delete_empty(self, acquire_lock=True):
|
def delete_empty(self, acquire_lock=True):
|
||||||
"""
|
"""
|
||||||
The argument `acquire_lock` controls whether or not this method
|
The argument `acquire_lock` controls whether or not this method
|
||||||
@@ -318,17 +316,18 @@ class IndexInstanceNode(MPTTModel):
|
|||||||
# parent template node for the lock
|
# parent template node for the lock
|
||||||
if acquire_lock:
|
if acquire_lock:
|
||||||
lock = locking_backend.acquire_lock(
|
lock = locking_backend.acquire_lock(
|
||||||
'indexing:indexing_template_node_{}'.format(
|
self.index_template_node.get_lock_string()
|
||||||
self.index_template_node.pk
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
# Start transaction after the lock in case the locking backend uses
|
# Start transaction after the lock in case the locking backend uses
|
||||||
# the database.
|
# the database.
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
if self.documents.count() == 0 and self.get_children().count() == 0:
|
if self.documents.count() == 0 and self.get_children().count() == 0:
|
||||||
if self.parent:
|
if self.parent:
|
||||||
self.delete()
|
|
||||||
self.parent.delete_empty(acquire_lock=False)
|
self.parent.delete_empty(acquire_lock=False)
|
||||||
|
# Delete ourselves after the parent is deleted
|
||||||
|
# Sound counterintuitive but otherwise the tree becomes
|
||||||
|
# corrupted. Reference: test_models.test_date_based_index
|
||||||
|
self.delete()
|
||||||
if acquire_lock:
|
if acquire_lock:
|
||||||
lock.release()
|
lock.release()
|
||||||
|
|
||||||
@@ -385,10 +384,9 @@ class IndexInstanceNode(MPTTModel):
|
|||||||
# parent template node for the lock
|
# parent template node for the lock
|
||||||
if acquire_lock:
|
if acquire_lock:
|
||||||
lock = locking_backend.acquire_lock(
|
lock = locking_backend.acquire_lock(
|
||||||
'indexing:indexing_template_node_{}'.format(
|
self.index_template_node.get_lock_string()
|
||||||
self.index_template_node.pk
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.documents.remove(document)
|
self.documents.remove(document)
|
||||||
self.delete_empty(acquire_lock=False)
|
self.delete_empty(acquire_lock=False)
|
||||||
|
|
||||||
|
|||||||
@@ -217,3 +217,38 @@ class IndexTestCase(DocumentTestMixin, BaseTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
Index.objects.rebuild()
|
Index.objects.rebuild()
|
||||||
|
|
||||||
|
def test_date_based_index(self):
|
||||||
|
index = Index.objects.create(label=TEST_INDEX_LABEL)
|
||||||
|
index.document_types.add(self.document_type)
|
||||||
|
|
||||||
|
level_year = index.node_templates.create(
|
||||||
|
parent=index.template_root,
|
||||||
|
expression='{{ document.date_added|date:"Y" }}',
|
||||||
|
link_documents=False
|
||||||
|
)
|
||||||
|
|
||||||
|
index.node_templates.create(
|
||||||
|
parent=level_year,
|
||||||
|
expression='{{ document.date_added|date:"m" }}',
|
||||||
|
link_documents=True
|
||||||
|
)
|
||||||
|
# Index the document created by default
|
||||||
|
Index.objects.rebuild()
|
||||||
|
|
||||||
|
self.document.delete()
|
||||||
|
|
||||||
|
# Uploading a new should not trigger an error
|
||||||
|
document = self.upload_document()
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
[instance.value for instance in IndexInstanceNode.objects.all().order_by('pk')],
|
||||||
|
[
|
||||||
|
'', force_text(document.date_added.year),
|
||||||
|
force_text(document.date_added.month).zfill(2)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
document in list(IndexInstanceNode.objects.order_by('pk').last().documents.all())
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user