Skip to content

Commit c1ee33b

Browse files
fix: race condition when picking an evaluation
1 parent c3b1f2c commit c1ee33b

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

src/shared/listeners/nix_evaluation.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,19 @@ class TooManyStuff(BaseException):
189189
async def evaluation_entrypoint(
190190
avg_eval_time: float, evaluation: NixEvaluation
191191
) -> None:
192+
already_completed = False
193+
192194
# Acquire an evaluation slot atomically: lock all IN_PROGRESS rows
193195
# to prevent concurrent workers from racing past the count check.
194196
def _try_acquire_slot() -> bool:
197+
nonlocal already_completed
195198
with transaction.atomic():
199+
if NixEvaluation.objects.filter(
200+
id=evaluation.pk,
201+
state=NixEvaluation.EvaluationState.COMPLETED,
202+
).exists():
203+
already_completed = True
204+
return True
196205
in_progress = (
197206
NixEvaluation.objects.select_for_update()
198207
.filter(state=NixEvaluation.EvaluationState.IN_PROGRESS)
@@ -210,6 +219,10 @@ def _try_acquire_slot() -> bool:
210219
# Add in average 30s as a jitter to enable clear winners during the grab for the evaluation slot.
211220
jitter = random.randint(1, 60)
212221
await asyncio.sleep(avg_eval_time + jitter)
222+
223+
if already_completed:
224+
return
225+
213226
repo = GitRepo(settings.LOCAL_NIXPKGS_CHECKOUT)
214227
start = time.time()
215228
try:

src/shared/tests/test_crash_signals.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ def test_zero_exit_marks_completed(
8484
assert waiting_evaluation.state == NixEvaluation.EvaluationState.COMPLETED
8585

8686

87-
@pytest.mark.xfail(strict=True, reason="Not implemented")
8887
@pytest.mark.django_db(transaction=True)
8988
def test_already_completed_evaluation_is_not_re_run(
9089
make_evaluation: Callable[..., NixEvaluation],

0 commit comments

Comments
 (0)