`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.
test/framework/src/main/java/org/elasticsearch/common/util/concurrent/DeterministicTaskQueue.java
@Override
            public long absoluteTimeInMillis() {
                return currentTimeMillis;
            }
            @Override
            public ThreadPoolInfo info() {
                throw new UnsupportedOperationException();
            }
            @Override
            public Info info(String name) {
                return infos.computeIfAbsent(name, n -> new Info(n, ThreadPoolType.FIXED, random.nextInt(10) + 1));
            }
            @Override
            public ThreadPoolStats stats() {
                throw new UnsupportedOperationException();
            }
            @Override
            public ExecutorService generic() {
                return executor(Names.GENERIC);
            }
            @Override
            public ExecutorService executor(String name) {
                return Names.SAME.equals(name) ? EsExecutors.DIRECT_EXECUTOR_SERVICE : forkingExecutor;
            }
            @Override
            public ScheduledCancellable schedule(Runnable command, TimeValue delay, Executor executor) {
                final int NOT_STARTED = 0;
                final int STARTED = 1;
                final int CANCELLED = 2;
                final AtomicInteger taskState = new AtomicInteger(NOT_STARTED);