docs: void stop() {
      stopAsync();
      try {
        // stopperThread is not null for sure
        // join() does nothing if thread already finished
        stopperThread.join();
        lifecycle.tryToMoveTo(Lifecycle.State.STOPPED);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
      exit.exit(0);
    }