org.elasticsearch.indices.recovery.RecoveryTarget#restoreFileFromSnapshot does not check for cancellation during the download of a file. This means that if a recovery is cancelled mid-way, we will still not release the store/shard-lock until the file is fully downloaded.
For large files or slow downloads this can lead to problems when the shard is (re-)allocated to a node that is still executing such an interrupted recovery.

-> we need to add some checks for cancellation here like we have for other recovery modes.
server/src/main/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetService.java
ActionListener.run(toSendListener.map(v -> {
                logger.trace("{} preparing shard for peer recovery", recoveryTarget.shardId());
                indexShard.prepareForIndexRecovery();
                if (indexShard.indexSettings().getIndexMetadata().isSearchableSnapshot()) {
                    
                    indexShard.getIndexEventListener().afterFilesRestoredFromRepository(indexShard);
                    final Store store = indexShard.store();
                    store.incRef();
                    try {
                        StoreRecovery.bootstrap(indexShard, store);
                    } finally {
                        store.decRef();
                    }
                }
                final long startingSeqNo = indexShard.recoverLocallyUpToGlobalCheckpoint();
                assert startingSeqNo == UNASSIGNED_SEQ_NO || recoveryTarget.state().getStage() == RecoveryState.Stage.TRANSLOG
                    : "unexpected recovery stage [" + recoveryTarget.state().getStage() + "] starting seqno [ " + startingSeqNo + "]";
                final var startRequest = getStartRecoveryRequest(logger, clusterService.localNode(), recoveryTarget, startingSeqNo);
                return new StartRecoveryRequestToSend(startRequest, PeerRecoverySourceService.Actions.START_RECOVERY, startRequest);
            }), indexShard::preRecovery);
        } else {
            toSendListener.onResponse(
                new StartRecoveryRequestToSend(
                    preExistingRequest,
                    PeerRecoverySourceService.Actions.REESTABLISH_RECOVERY,
                    new ReestablishRecoveryRequest(recoveryId, preExistingRequest.shardId(), preExistingRequest.targetAllocationId())
                )
            );
        }
    }