When a shard is to be snapshotted, we acquire a store ref (wrapped in an index commit) and then enqueue the shard snapshot task for execution by the repository:

https://github.com/elastic/elasticsearch/blob/b124763772748d8993911e4a7ba94b17472a9539/server/src/main/java/org/elasticsearch/snapshots/SnapshotShardsService.java#L369-L384

If the shard is closed while its snapshot is in the queue then it looks like we do not release the store ref promptly. Instead, we keep hold of it until it reaches the front of the queue, which could be many minutes later. During this time the shard cannot fully shut down and release the shard lock, leading to a `ShardLockObtainFailedException` being thrown on attempts to reinitialise the shard.
server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java
* IO buffer size hint  reading and writing to the underlying blob store.
     */
    protected final int bufferSize;
    /**
     * Maximum number of snapshots that this repository can hold.
     */
    private final int maxSnapshotCount;
    private final ShardSnapshotTaskRunner shardSnapshotTaskRunner;
    /**
     * Constructs new BlobStoreRepository
     * @param metadata   The metadata  this repository including name and settings
     * @param clusterService ClusterService
     */
    protected BlobStoreRepository(
        final RepositoryMetadata metadata,
        final NamedXContentRegistry namedXContentRegistry,
        final ClusterService clusterService,
        final BigArrays bigArrays,
        final RecoverySettings recoverySettings,
        final BlobPath basePath
    ) {
        this.metadata = metadata;
        this.threadPool = clusterService.getClusterApplierService().threadPool();
        this.clusterService = clusterService;
        this.bigArrays = bigArrays;
        this.recoverySettings = recoverySettings;
        this.compress = COMPRESS_SETTING.get(metadata.settings());
        this.supportURLRepo = SUPPORT_URL_REPO.get(metadata.settings());
        snapshotRateLimiter = getSnapshotRateLimiter();
        restoreRateLimiter = getRestoreRateLimiter();