`GatewayService` implements logic for delaying state recovery in the cluster until enough data nodes have joined and/or some timeout has occurred. The implementation is pretty old and doesn't make use of much modern infrastructure for doing this kind of thing, making it pretty hard to follow and to improve (see e.g. #86588). We should clean it up and simplify it.
server/src/main/java/org/elasticsearch/gateway/GatewayService.java
}
        } else {
            if (recoveryInProgress.compareAndSet(false, true)) {
                try {
                    logger.debug("performing state recovery...");
                    runRecovery();
                } catch (Exception e) {
                    logger.warn("state recovery failed", e);
                    resetRecoveredFlags();
                }
            }
        }
    }
    private void resetRecoveredFlags() {
        recoveryInProgress.set(false);
        scheduledRecovery.set(false);
    }
    private static final String TASK_SOURCE = "local-gateway-elected-state";
    class RecoverStateUpdateTask extends ClusterStateUpdateTask {
        @Override
        public ClusterState execute(final ClusterState currentState) {
            if (currentState.blocks().hasGlobalBlock(STATE_NOT_RECOVERED_BLOCK) == false) {
                logger.debug("cluster is already recovered");
                return currentState;
            }
            return ClusterStateUpdaters.removeStateNotRecoveredBlock(
                ClusterStateUpdaters.updateRoutingTable(currentState, shardRoutingRoleStrategy)
            );
        }
        @Override