diff --git a/invenio_rdm_records/services/components/pids.py b/invenio_rdm_records/services/components/pids.py index 8a08a67b2..420153429 100644 --- a/invenio_rdm_records/services/components/pids.py +++ b/invenio_rdm_records/services/components/pids.py @@ -17,7 +17,7 @@ from invenio_drafts_resources.services.records.uow import ParentRecordCommitOp from invenio_records_resources.services.uow import TaskOp -from ..pids.tasks import register_or_update_pid +from ..pids.tasks import register_or_update_pid, cleanup_parent_pids class PIDsComponent(ServiceComponent): @@ -212,6 +212,11 @@ def delete_record(self, identity, data=None, record=None, uow=None): self.service.pids.parent_pid_manager.discard_all( parent_pids, soft_delete=True ) + else: + # We're sending a task in case there is a race condition with two + # versions being deleted at the same time to ensure that we have + # consistent database state + self.uow.register(TaskOp(cleanup_parent_pids, record["id"])) # Async register/update tasks after transaction commit. for scheme in parent_pids.keys(): diff --git a/invenio_rdm_records/services/pids/tasks.py b/invenio_rdm_records/services/pids/tasks.py index bca558d82..2c13f882d 100644 --- a/invenio_rdm_records/services/pids/tasks.py +++ b/invenio_rdm_records/services/pids/tasks.py @@ -7,6 +7,8 @@ """RDM PIDs Service tasks.""" +from copy import copy + from celery import shared_task from invenio_access.permissions import system_identity @@ -22,3 +24,12 @@ def register_or_update_pid(recid, scheme, parent=False): scheme=scheme, parent=parent, ) + + +@shared_task(ignore_result=True) +def cleanup_parent_pids(record): + """Clean up parent PIDs which could not be deleted by the service.""" + record_cls = current_rdm_records.records_service + parent_pids = copy(record.parent.get("pids", {})) + if record_cls.next_latest_published_record_by_parent(record.parent) is None: + record_cls.pids.parent_pid_manager.discard_all(parent_pids, soft_delete=True)