Skip to content
Snippets Groups Projects
Commit 4f364cd8 authored by Bastien Abadie's avatar Bastien Abadie
Browse files

Merge branch 'element-path-stale-reads' into 'master'

Fix lots of potential stale reads in Element.add_parent and .remove_child

See merge request !1506
parents f76a2f5f 516ef7f7
No related branches found
No related tags found
1 merge request!1506Fix lots of potential stale reads in Element.add_parent and .remove_child
......@@ -221,7 +221,7 @@ class Element(IndexableModel):
delete_element(self.id)
Element.objects.filter(id=self.id)._raw_delete(using='default')
@transaction.atomic(using="default")
@transaction.atomic
def add_parent(self, parent, skip_children=False):
'''
Add an element as ancestor
......@@ -230,12 +230,12 @@ class Element(IndexableModel):
# Load existing paths on current element, and the parent paths
# in a single query
paths = ElementPath.objects.filter(element_id__in=(self.id, parent.id)).values('element_id', 'path')
paths = ElementPath.objects.using('default').filter(element_id__in=(self.id, parent.id)).values('element_id', 'path')
existing_paths = [p['path'] for p in paths if p['element_id'] == self.id]
parent_paths = [p['path'] for p in paths if p['element_id'] == parent.id]
# Get the next order for this type in the parent
order = parent.get_next_order(self.type)
order = parent.get_next_order(self.type_id)
# Build all parent paths needed
if not parent_paths:
......@@ -262,10 +262,10 @@ class Element(IndexableModel):
order,
))
# Update children's paths in a non optimized way as this is pretty rare
# Update children's paths in a non optimized way
if skip_children is False:
to_delete = []
children = ElementPath.objects.filter(path__contains=[self.id])
children = ElementPath.objects.using('default').filter(path__contains=[self.id])
for child in children:
base_path = child.path
......@@ -299,7 +299,7 @@ class Element(IndexableModel):
Uses the primary database to avoid stale reads and duplicate orderings,
and path__overlap to let Postgres use the GIN index before filtering by last item.
"""
assert isinstance(type, ElementType)
assert isinstance(type, (ElementType, uuid.UUID))
return ElementPath.objects \
.using('default') \
.filter(path__overlap=[self.id], path__last=self.id, element__type=type) \
......@@ -313,16 +313,16 @@ class Element(IndexableModel):
assert isinstance(child, Element)
# Check child is a direct child of this element
if not ElementPath.objects.filter(element=child, path__last=self.id).exists():
if not ElementPath.objects.using('default').filter(element=child, path__last=self.id).exists():
return
new_epaths = {}
# If child doesn't have any other parent, updates are needed
if not ElementPath.objects.filter(element=child).exclude(path__last=self.id).exists():
if not ElementPath.objects.using('default').filter(element=child).exclude(path__last=self.id).exists():
# Get all the child's children's paths
children_epaths = list(ElementPath.objects.filter(
children_epaths = list(ElementPath.objects.using('default').filter(
element__in=Element.objects.get_descending(child.id),
path__contains=[self.id]
))
......
......@@ -65,16 +65,6 @@ FROM "documents_elementpath"
WHERE "documents_elementpath"."element_id" IN ('{source_id}'::uuid,
'{destination_id}'::uuid);
SELECT "documents_elementtype"."id",
"documents_elementtype"."corpus_id",
"documents_elementtype"."slug",
"documents_elementtype"."display_name",
"documents_elementtype"."folder",
"documents_elementtype"."indexable"
FROM "documents_elementtype"
WHERE "documents_elementtype"."id" = '{page_type_id}'::uuid
LIMIT 21;
SELECT (MAX("documents_elementpath"."ordering") + 1) AS "max"
FROM "documents_elementpath"
INNER JOIN "documents_element" ON ("documents_elementpath"."element_id" = "documents_element"."id")
......
......@@ -56,16 +56,6 @@ FROM "documents_elementpath"
WHERE "documents_elementpath"."element_id" IN ('{source_id}'::uuid,
'{destination_id}'::uuid);
SELECT "documents_elementtype"."id",
"documents_elementtype"."corpus_id",
"documents_elementtype"."slug",
"documents_elementtype"."display_name",
"documents_elementtype"."folder",
"documents_elementtype"."indexable"
FROM "documents_elementtype"
WHERE "documents_elementtype"."id" = '{page_type_id}'::uuid
LIMIT 21;
SELECT (MAX("documents_elementpath"."ordering") + 1) AS "max"
FROM "documents_elementpath"
INNER JOIN "documents_element" ON ("documents_elementpath"."element_id" = "documents_element"."id")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment