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
retryOnMappingException.accept(e);
                    } else {
                        listener.onFailure(e);
                    }
                })
            );
        }
    }
    private abstract class RecoveryRequestHandler<T extends RecoveryTransportRequest> implements TransportRequestHandler<T> {
        @Override
        public final void messageReceived(final T request, TransportChannel channel, Task task) throws Exception {
            try (RecoveryRef recoveryRef = onGoingRecoveries.getRecoverySafe(request.recoveryId(), request.shardId())) {
                final RecoveryTarget recoveryTarget = recoveryRef.target();
                final ActionListener<Void> resultListener = new ChannelActionListener<>(channel).map(responseMapping(recoveryTarget));
                final long requestSeqNo = request.requestSeqNo();
                final ActionListener<Void> listener = requestSeqNo == SequenceNumbers.UNASSIGNED_SEQ_NO
                    ? resultListener
                    : recoveryTarget.markRequestReceivedAndCreateListener(requestSeqNo, resultListener);
                if (listener != null) {
                    handleRequest(request, recoveryTarget, listener);
                }
            }
        }
        protected CheckedFunction<Void, TransportResponse, Exception> responseMapping(RecoveryTarget recoveryTarget) {
            return v -> TransportResponse.Empty.INSTANCE;
        }
        protected abstract void handleRequest(T request, RecoveryTarget target, ActionListener<Void> listener) throws IOException;
    }
    private class FileChunkTransportRequestHandler extends RecoveryRequestHandler<RecoveryFileChunkRequest> {