The per-job Yarn cluster doesn't stop after cancel a running job if the job restarted many times, like 1000 times, in a short time.
The bug is in archiveExecutionGraph() phase before executing removeJobAndRegisterTerminationFuture(). The CompletableFuture thread will exit unexpectedly with NullPointerException in archiveExecutionGraph() phase. It's hard to find that because here it only catches IOException. In SubtaskExecutionAttemptDetailsHandler and SubtaskExecutionAttemptAccumulatorsHandler, when calling archiveJsonWithPath() method, it will construct some json information about prior execution attempts but the index is from 0 which might be dropped index for the for loop. In default, it will return null when trying to get the prior execution attempt (AccessExecution attempt = subtask.getPriorExecutionAttempt).