https://github.com/elastic/elasticsearch/blob/099fb84cfcf87be6689c3516674f45438bafa767/server/src/main/java/org/elasticsearch/action/ActionListener.java#L420-L432

Rather than keeping hold of the `delegate` and using an `AtomicBoolean` to track the completion, we could use an `AtomicReference` and drop the whole listener on completion, which might free up heap in some fail-fast cases.
server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexStateService.java
final IndexMetadata indexMetadata = currentState.metadata().getIndexSafe(index);
            if (indexMetadata.getState() != IndexMetadata.State.CLOSE) {
                indicesToClose.add(index);
            } else {
                logger.debug("index {} is already closed, ignoring", index);
                assert currentState.blocks().hasIndexBlock(index.getName(), INDEX_CLOSED_BLOCK);
            }
        }
        if (indicesToClose.isEmpty()) {
            return currentState;
        }
        
        Set<Index> restoringIndices = RestoreService.restoringIndices(currentState, indicesToClose);
        if (restoringIndices.isEmpty() == false) {
            throw new IllegalArgumentException("Cannot close indices that are being restored: " + restoringIndices);
        }
        
        Set<Index> snapshottingIndices = SnapshotsService.snapshottingIndices(currentState, indicesToClose);
        if (snapshottingIndices.isEmpty() == false) {
            throw new SnapshotInProgressException(
                "Cannot close indices that are being snapshotted: "
                    + snapshottingIndices
                    + ". Try again after snapshot finishes or cancel the currently running snapshot."
            );
        }
        final ClusterBlocks.Builder blocks = ClusterBlocks.builder(currentState.blocks());
        for (Index index : indicesToClose) {
            ClusterBlock indexBlock = null;
            final Set<ClusterBlock> clusterBlocks = currentState.blocks().indices().get(index.getName());
            if (clusterBlocks != null) {