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
private final IndexMetadataVerifier indexMetadataVerifier;
    private final IndicesService indicesService;
    private final ShardLimitValidator shardLimitValidator;
    private final NodeClient client;
    private final ThreadPool threadPool;
    private final ClusterStateTaskExecutor<OpenIndicesTask> opensExecutor;
    private final ClusterStateTaskExecutor<AddBlocksToCloseTask> addBlocksToCloseExecutor;
    private final ClusterStateTaskExecutor<CloseIndicesTask> closesExecutor;
    private final ClusterStateTaskExecutor<AddBlocksTask> addBlocksExecutor;
    private final ClusterStateTaskExecutor<FinalizeBlocksTask> finalizeBlocksExecutor;
    @Inject
    public MetadataIndexStateService(
        ClusterService clusterService,
        AllocationService allocationService,
        IndexMetadataVerifier indexMetadataVerifier,
        IndicesService indicesService,
        ShardLimitValidator shardLimitValidator,
        NodeClient client,
        ThreadPool threadPool
    ) {
        this.clusterService = clusterService;
        this.allocationService = allocationService;
        this.indexMetadataVerifier = indexMetadataVerifier;
        this.indicesService = indicesService;
        this.shardLimitValidator = shardLimitValidator;
        this.client = client;
        this.threadPool = threadPool;
        this.opensExecutor = new OpenIndicesExecutor();
        this.addBlocksToCloseExecutor = new AddBlocksToCloseExecutor();
        this.closesExecutor = new CloseIndicesExecutor();