Actions `cluster:admin/repository/analyze/blob` and `cluster:admin/repository/analyze/register` and so on are only invoked via the transport service, they do not need to register as client actions so we can drop the `ActionType` instance. Instead the root `RepositoryAnalyzeAction` should create and register all these transport actions itself. But even the root `RepositoryAnalyzeAction` should not be an `ActionType` derivative, we should just declare an `ActionType` instance directly. Moreover we can use `ActionType#localOnly` since the client action does not run on remote clusters.
x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalyzeAction.java
this.listener = ActionListener.runBefore(listener, () -> cancellationListener.onResponse(null));
            responses = new ArrayList<>(request.blobCount);
        }
        private boolean setFirstFailure(Exception e) {
            if (failure.compareAndSet(null, e)) {
                transportService.getTaskManager().cancelTaskAndDescendants(task, "task failed", false, ActionListener.noop());
                return true;
            } else {
                return false;
            }
        }
        private void fail(Exception e) {
            if (setFirstFailure(e) == false) {
                if (innerFailures.tryAcquire()) {
                    final Throwable cause = ExceptionsHelper.unwrapCause(e);
                    if (cause instanceof TaskCancelledException || cause instanceof ReceiveTimeoutTransportException) {
                        innerFailures.release();
                    } else {
                        failure.get().addSuppressed(e);
                    }
                }
            }
        }
        /**
         * Check that we haven't already failed (including cancellation and timing out).
         */
        private boolean isRunning() {
            return failure.get() == null;
        }
        private class CheckForCancelListener implements ActionListener<Void> {