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
}
        container.deleteBlobsIgnoringIfNotExists(wrappedIterator);
    }
    private BlobPath indicesPath() {
        return basePath().add("indices");
    }
    private BlobContainer indexContainer(IndexId indexId) {
        return blobStore().blobContainer(indexPath(indexId));
    }
    private BlobContainer shardContainer(IndexId indexId, ShardId shardId) {
        return shardContainer(indexId, shardId.getId());
    }
    private BlobPath indexPath(IndexId indexId) {
        return indicesPath().add(indexId.getId());
    }
    private BlobPath shardPath(IndexId indexId, int shardId) {
        return indexPath(indexId).add(Integer.toString(shardId));
    }
    public BlobContainer shardContainer(IndexId indexId, int shardId) {
        return blobStore().blobContainer(shardPath(indexId, shardId));
    }
    /**
     * Configures RateLimiter based on repository and global settings
     *
     * @param rateLimiter              the ing rate limiter to configure (or null if no throttling was previously needed)
     * @param maxConfiguredBytesPerSec the configured max bytes per sec from the settings
     * @param settingKey               setting used to configure the rate limiter
     * @param warnIfOverRecovery       log a warning if rate limit setting is over the effective recovery rate limit
     * @return the newly configured rate limiter or null if no throttling is needed
     */