private void createStateMachineDotGraph()

in genie-agent/src/main/java/com/netflix/genie/agent/cli/InfoCommand.java [215:338]


    private void createStateMachineDotGraph(
        final List<ExecutionStage> stages,
        final StringBuilder messageBuilder
    ) {
        final List<States> states = Lists.newArrayList();

        states.add(States.INITIAL_STATE);
        stages.forEach(stage -> states.add(stage.getState()));
        states.add(States.FINAL_STATE);

        final List<Pair<States, States>> transitions = Lists.newArrayList();

        for (int i = 0; i < states.size() - 1; i++) {
            transitions.add(Pair.of(states.get(i), states.get(i + 1)));
        }

        messageBuilder
            .append("digraph state_machine {")
            .append(NEWLINE);

        messageBuilder
            .append("  // States")
            .append(NEWLINE);


        states.forEach(
            state -> {
                final String shape;
                if (state == States.INITIAL_STATE) {
                    shape = "shape=diamond";
                } else if (state == States.FINAL_STATE) {
                    shape = "shape=rectangle";
                } else {
                    shape = "";
                }

                final String edgeTickness;
                if (state.isCriticalState()) {
                    edgeTickness = "penwidth=3.0";
                } else {
                    edgeTickness = "";
                }

                messageBuilder
                    .append("  ")
                    .append(state.name())
                    .append(" [label=")
                    .append(state.name())
                    .append(" ")
                    .append(shape)
                    .append(" ")
                    .append(edgeTickness)
                    .append("]")
                    .append(NEWLINE);
            }
        );

        messageBuilder
            .append("  // Transitions")
            .append(NEWLINE);

        transitions.forEach(
            transition ->
                messageBuilder
                    .append("  ")
                    .append(transition.getLeft())
                    .append(" -> ")
                    .append(transition.getRight())
                    .append(NEWLINE)
        );

        messageBuilder
            .append("  // Skip transitions")
            .append(NEWLINE);

        // Draw an edge from a state whose next state is skippable to the next non-skippable state.
        for (int i = 0; i < states.size() - 2; i++) {
            final States state = states.get(i);
            final boolean skipNext = states.get(i + 1).isSkippedDuringAbortedExecution();
            if (skipNext) {
                // Find the next non-skipped stage
                for (int j = i + 1; j < states.size() - 1; j++) {
                    final States nextState = states.get(j);
                    if (!nextState.isSkippedDuringAbortedExecution()) {
                        messageBuilder
                            .append("  ")
                            .append(state)
                            .append(" -> ")
                            .append(nextState)
                            .append(" [style=dotted]")
                            .append(NEWLINE);
                        break;
                    }
                }
            }
        }

        messageBuilder
            .append("  // Retry transitions")
            .append(NEWLINE);

        states.forEach(
            state -> {
                final @Min(0) int retries = state.getTransitionRetries();
                if (retries > 0) {
                    messageBuilder
                        .append("  ")
                        .append(state)
                        .append(" -> ")
                        .append(state)
                        .append(" [style=dashed label=\"")
                        .append(retries)
                        .append(" retries\"]")
                        .append(NEWLINE);
                }
            }
        );

        messageBuilder
            .append("}")
            .append(NEWLINE)
            .append("// ------------------------------------------------------------------------")
            .append(NEWLINE);
    }