Skip to content

Commit c04f50e

Browse files
author
Nils Bars
committed
Handle concurrent exercise deletion gracefully
Redirect instead of aborting when an exercise was already deleted by a concurrent request that held the DB advisory lock.
1 parent 13cc98b commit c04f50e

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

webapp/ref/view/exercise.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,15 @@ def render():
283283
def exercise_delete(exercise_id):
284284
exercise = Exercise.query.filter(Exercise.id == exercise_id).first()
285285
if not exercise:
286-
flash.error(f"Unknown exercise ID {exercise_id}")
287-
abort(400)
286+
# Exercise already deleted. This can happen when a concurrent request was blocked
287+
# on the global DB advisory lock while the first request performed slow Docker
288+
# operations (container/image removal) and then deleted the exercise.
289+
return redirect_to_next()
290+
291+
# TODO: The slow Docker operations (instance removal, image deletion) hold the global
292+
# DB lock for the entire duration, blocking all other requests. Moving them to a
293+
# background thread would help, but introduces challenges keeping DB and Docker state
294+
# in sync.
288295

289296
instances = exercise.instances
290297
if instances:

0 commit comments

Comments
 (0)