We are noticing some issues when updating routes via Terraform because when receiving multiple concurrent requests updating position, the order is updated in a transaction but it is then tried to save again in the .save call, which could lead to IntegrityErrors, because the order may have been updated in a concurrent request meanwhile.
Test run with the reproduced error (before the serializer update):
_____________________________ test_ordered_model_swap_all_to_zero_via_serializer _____________________________
@pytest.mark.django_db(transaction=True)
def test_ordered_model_swap_all_to_zero_via_serializer():
THREADS = 300
exceptions = []
TestOrderedModel.objects.all().delete() # clear table
instances = [TestOrderedModel.objects.create(test_field="test") for _ in range(THREADS)]
# generate random non-unique orders
random.seed(42)
positions = [random.randint(0, THREADS - 1) for _ in range(THREADS)]
def update_order_to_zero(idx):
try:
instance = instances[idx]
serializer = TestOrderedModelSerializer(
instance, data={"order": 0, "extra_field": idx}, partial=True
)
serializer.is_valid(raise_exception=True)
serializer.save()
instance.swap(positions[idx])
except Exception as e:
exceptions.append(e)
threads = [threading.Thread(target=update_order_to_zero, args=(0,)) for _ in range(THREADS)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
# can only check that orders are still sequential and that there are no exceptions
# can't check the exact order because it changes depending on the order of execution
> assert not exceptions
E assert not [IntegrityError(1062, "Duplicate entry 'test-0' for key 'base_testorderedmodel.unique_test_field_order'"), IntegrityEr...rder'"), IntegrityError(1062, "Duplicate entry 'test-0' for key 'base_testorderedmodel.unique_test_field_order'"), ...]
THREADS = 300
exceptions = [IntegrityError(1062, "Duplicate entry 'test-0' for key 'base_testorderedmodel.unique_test_field_order'"), IntegrityEr...rder'"), IntegrityError(1062, "Duplicate entry 'test-0' for key 'base_testorderedmodel.unique_test_field_order'"), ...]
instances = [<TestOrderedModel: TestOrderedModel object (841)>, <TestOrderedModel: TestOrderedModel object (842)>, <TestOrderedMod...ject (844)>, <TestOrderedModel: TestOrderedModel object (845)>, <TestOrderedModel: TestOrderedModel object (846)>, ...]
positions = [57, 12, 140, 125, 114, 71, ...]
thread = <Thread(Thread-302 (update_order_to_zero), stopped 139636013323840)>
threads = [<Thread(Thread-3 (update_order_to_zero), stopped 139646722418240)>, <Thread(Thread-4 (update_order_to_zero), stopped ...ate_order_to_zero), stopped 139646608590400)>, <Thread(Thread-8 (update_order_to_zero), stopped 139646600197696)>, ...]
update_order_to_zero = <function test_ordered_model_swap_all_to_zero_via_serializer.<locals>.update_order_to_zero at 0x7f02086274c0>
common/tests/test_ordered_model.py:481: AssertionError
We are noticing some issues when updating routes via Terraform because when receiving multiple concurrent requests updating position, the order is updated in a transaction but it is then tried to save again in the
.save
call, which could lead toIntegrityError
s, because the order may have been updated in a concurrent request meanwhile.Test run with the reproduced error (before the serializer update):