Skip to content

Commit 2149c0c

Browse files
committed
call remove unused chunks async job
1 parent 88e5490 commit 2149c0c

3 files changed

Lines changed: 30 additions & 6 deletions

File tree

server/mergin/sync/public_api_v2_controller.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from marshmallow import ValidationError
1515
from sqlalchemy.exc import IntegrityError
1616

17+
from mergin.sync.tasks import remove_transaction_chunks
18+
1719
from .schemas_v2 import ProjectSchema as ProjectSchemaV2
1820
from ..app import db
1921
from ..auth import auth_required
@@ -318,6 +320,14 @@ def create_project_version(id):
318320
temp_files_dir = os.path.join(upload.upload_dir, "files", v_next_version)
319321
os.renames(temp_files_dir, version_dir)
320322

323+
# remove used chunks
324+
# get chunks from added and updated files
325+
chunks_ids = []
326+
for file in to_be_added_files + to_be_updated_files:
327+
file_chunks = file.get("chunks", [])
328+
chunks_ids.extend(file_chunks)
329+
remove_transaction_chunks.delay(chunks_ids)
330+
321331
logging.info(
322332
f"Push finished for project: {project.id}, project version: {v_next_version}, upload id: {upload.id}."
323333
)

server/mergin/sync/tasks.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .models import Project, ProjectVersion, FileHistory
1414
from .storages.disk import move_to_tmp
1515
from .config import Configuration
16-
from .utils import remove_outdated_files
16+
from .utils import get_chunk_location, remove_outdated_files
1717
from ..celery import celery
1818
from ..app import db
1919

@@ -169,3 +169,12 @@ def remove_unused_chunks():
169169
if not os.path.isdir(dir):
170170
continue
171171
remove_outdated_files(dir, time_delta)
172+
173+
174+
@celery.task
175+
def remove_transaction_chunks(chunks=[]):
176+
"""Remove chunks related to a specific sync transaction"""
177+
for chunk in chunks:
178+
chunk_path = get_chunk_location(chunk)
179+
if os.path.exists(chunk_path):
180+
os.remove(chunk_path)

server/mergin/tests/test_public_api_v2.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-MerginMaps-Commercial
44

5-
from mergin.sync.tasks import remove_unused_chunks
5+
from mergin.sync.tasks import remove_transaction_chunks, remove_unused_chunks
66
from . import DEFAULT_USER
77
from .utils import (
88
add_user,
@@ -358,6 +358,7 @@ def test_create_version(client, data, expected, err_code):
358358
assert project.latest_version == 1
359359

360360
chunks = []
361+
chunk_ids = []
361362
if expected == 201:
362363
# mimic chunks were uploaded
363364
for f in data["changes"]["added"] + data["changes"]["updated"]:
@@ -374,17 +375,21 @@ def test_create_version(client, data, expected, err_code):
374375
out_file.write(in_file.read(CHUNK_SIZE))
375376

376377
chunks.append(chunk_location)
378+
chunk_ids.append(chunk)
377379

378-
response = client.post(f"v2/projects/{project.id}/versions", json=data)
380+
with patch(
381+
"mergin.sync.public_api_v2_controller.remove_transaction_chunks.delay"
382+
) as mock_remove:
383+
response = client.post(f"v2/projects/{project.id}/versions", json=data)
379384
assert response.status_code == expected
380-
# mock chunks expiration to check if removed
381385
if expected == 201:
382386
assert response.json["version"] == "v2"
383387
assert project.latest_version == 2
384388
# chunks exists after upload, cleanup job did not remove them
385389
assert all(os.path.exists(chunk) for chunk in chunks)
386-
with patch.object(SyncConfiguration, "UPLOAD_CHUNKS_EXPIRATION", 0):
387-
remove_unused_chunks()
390+
if chunk_ids:
391+
assert mock_remove.called_once_with(chunk_ids)
392+
remove_transaction_chunks(chunk_ids)
388393
assert all(not os.path.exists(chunk) for chunk in chunks)
389394
else:
390395
assert project.latest_version == 1

0 commit comments

Comments
 (0)