From 4a213a9d8e4f2505e57f59efe152bd1a2ea80f84 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.anjos@idiap.ch> Date: Fri, 20 May 2016 11:30:42 +0200 Subject: [PATCH] [experiments] Improve on job parent searching to avoid double-assignment --- beat/web/experiments/models.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/beat/web/experiments/models.py b/beat/web/experiments/models.py index 6114d2944..b4279b74e 100644 --- a/beat/web/experiments/models.py +++ b/beat/web/experiments/models.py @@ -1020,11 +1020,21 @@ class Block(models.Model): from ..backend.models import Job - # search for other jobs with similar outputs and has no children yet - similar = Job.objects.select_for_update().filter(\ - block__outputs__in=self.outputs.all(), child=None).first() - - Job(block=self, parent=similar).save() + # search for other jobs with similar outputs that have no children yet + # do this carefully, as other experiments may be scheduled at the same + # time, invalidating our "parent" choice + parent = Job.objects.filter(block__outputs__in=self.outputs.all(), + child=None).first() + if parent is not None: #(candidate only) try to lock it + while True: + parent = Job.objects.select_for_update().get(pk=parent.pk) + if parent.child_ is not None: #was taken meanwhile, retry + parent = parent.child + continue + Job(block=self, parent=parent).save() + break + else: + Job(block=self).save() # checks if the job is immediately runnable - if so, tries to # make it runnable (check caches and other) -- GitLab