Skip to content

Commit

Permalink
Add locking to asset update/delete at API level
Browse files Browse the repository at this point in the history
  • Loading branch information
jjnesbitt committed Feb 15, 2023
1 parent 96ad298 commit 107a20c
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions dandiapi/api/views/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import os.path

from django.conf import settings
from django.db import transaction
from django.db.models import QuerySet
from django.http import HttpResponseRedirect
from django.utils.decorators import method_decorator
Expand Down Expand Up @@ -316,14 +317,19 @@ def update(self, request, versions__dandiset__pk, versions__version, **kwargs):
serializer = AssetRequestSerializer(data=self.request.data)
serializer.is_valid(raise_exception=True)

asset, _ = change_asset(
user=request.user,
asset=self.get_object(),
version=version,
new_asset_blob=serializer.get_blob(),
new_zarr_archive=serializer.get_zarr_archive(),
new_metadata=serializer.validated_data['metadata'],
)
# Lock asset for update
with transaction.atomic():
locked_asset = get_object_or_404(
version.assets.select_for_update(), id=self.get_object().id
)
asset, _ = change_asset(
user=request.user,
asset=locked_asset,
version=version,
new_asset_blob=serializer.get_blob(),
new_zarr_archive=serializer.get_zarr_archive(),
new_metadata=serializer.validated_data['metadata'],
)

serializer = AssetDetailSerializer(instance=asset)
return Response(serializer.data, status=status.HTTP_200_OK)
Expand All @@ -338,14 +344,18 @@ def update(self, request, versions__dandiset__pk, versions__version, **kwargs):
Only draft versions can be modified.',
)
def destroy(self, request, versions__dandiset__pk, versions__version, **kwargs):
asset = self.get_object()
version = get_object_or_404(
Version,
dandiset__pk=versions__dandiset__pk,
version=versions__version,
)

remove_asset_from_version(user=request.user, asset=asset, version=version)
# Lock asset for delete
with transaction.atomic():
locked_asset = get_object_or_404(
version.assets.select_for_update(), id=self.get_object().id
)
remove_asset_from_version(user=request.user, asset=locked_asset, version=version)

return Response(None, status=status.HTTP_204_NO_CONTENT)

Expand Down

0 comments on commit 107a20c

Please sign in to comment.