In https://github.com/elastic/elasticsearch/pull/78547 we introduced batching for the ILM master tasks that occur on the happy path. However if a high-shard-count cluster encounters problems while doing ILM-related things—perhaps some nodes are temporarily unavailable for taking a snapshot—then we process the resulting `ilm-retry-failed-step` and `ilm-move-to-error-step` tasks one-by-one which can significantly delay the cluster's recovery from its problems.

We should batch these things together too.

It looks like we also enqueue duplicate `ilm-retry-failed-step` on each poll interval too, although we do appear to treat the duplicates as no-ops at execution time.

Relates https://github.com/elastic/elasticsearch/issues/77466
x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java
LifecycleExecutionState lifecycleState = indexMetadata.getLifecycleExecutionState();
        Step failedStep = stepRegistry.getStep(
            indexMetadata,
            new StepKey(lifecycleState.phase(), lifecycleState.action(), lifecycleState.failedStep())
        );
        if (failedStep == null) {
            logger.warn(
                "failed step [{}] for index [{}] is not part of policy [{}] anymore, or it is invalid. skipping execution",
                lifecycleState.failedStep(),
                index,
                policy
            );
            return;
        }
        if (lifecycleState.isAutoRetryableError() != null && lifecycleState.isAutoRetryableError()) {
            int currentRetryAttempt = lifecycleState.failedStepRetryCount() == null ? 1 : 1 + lifecycleState.failedStepRetryCount();
            logger.info(
                "policy [{}] for index [{}] on an error step due to a transient error, moving back to the failed "
                    + "step [{}] for execution. retry attempt [{}]",
                policy,
                index,
                lifecycleState.failedStep(),
                currentRetryAttempt
            );
            
            
            
            clusterService.submitStateUpdateTask(
                String.format(
                    Locale.ROOT,