Skip to content

Commit a436a00

Browse files
committed
Implement upload directory creation and lockfile handling in create_project_version
1 parent 4de3a0b commit a436a00

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

server/mergin/sync/public_api_v2_controller.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,23 @@ def create_project_version(id):
295295
if request.json.get("check_only", False):
296296
return NoContent, 204
297297

298+
upload_dir = None
298299
try:
299300
# while processing data, block other uploads
300301
upload = Upload(project, version, upload_changes, current_user.id)
301302
db.session.add(upload)
303+
# Save path as local before any potential rollback expires the ORM instance
304+
upload_dir = upload.upload_dir
305+
# Create dir and lockfile BEFORE committing so concurrent is_active() checks
306+
# always see this upload as active once its DB row is visible to other workers.
307+
os.makedirs(upload_dir)
308+
open(upload.lockfile, "w").close()
302309
# Creating blocking upload can fail, e.g. in case of racing condition
303310
db.session.commit()
304311
except IntegrityError:
305312
db.session.rollback()
313+
if upload_dir:
314+
move_to_tmp(upload_dir)
306315
# check and clean dangling blocking uploads or abort
307316
for current_upload in project.uploads.all():
308317
if current_upload.is_active():
@@ -321,16 +330,17 @@ def create_project_version(id):
321330
# Try again after cleanup
322331
upload = Upload(project, version, upload_changes, current_user.id)
323332
db.session.add(upload)
333+
upload_dir = upload.upload_dir
334+
os.makedirs(upload_dir)
335+
open(upload.lockfile, "w").close()
324336
db.session.commit()
325-
move_to_tmp(upload.upload_dir)
326337
except IntegrityError as err:
338+
db.session.rollback()
339+
if upload_dir:
340+
move_to_tmp(upload_dir)
327341
logging.error(f"Failed to create upload session: {str(err)}")
328342
return AnotherUploadRunning().response(409)
329343

330-
# Create transaction folder and lockfile
331-
os.makedirs(upload.upload_dir)
332-
open(upload.lockfile, "w").close()
333-
334344
file_changes, errors = upload.process_chunks(use_shared_chunk_dir=True)
335345
# files consistency or geodiff related issues, project push would never succeed, whole upload is aborted
336346
if errors:

0 commit comments

Comments
 (0)