final def nonExitingMain()

in util-app/src/main/scala/com/twitter/app/App.scala [424:481]


  final def nonExitingMain(args: Array[String]): Unit = {
    observe(Register) {
      App.register(this)
    }
    observe(LoadBindings) {
      loadServiceBindings.foreach { binding => LoadService.bind(binding) }
    }
    observe(Init) {
      for (f <- inits) f()
    }
    observe(ParseArgs) {
      parseArgs(args)
    }
    observe(PreMain) {
      for (f <- premains) f()
    }
    observe(Main) {
      // Get a main() if it's defined. It's possible to define traits that only use pre/post mains.
      val mainMethod =
        try Some(getClass.getMethod("main"))
        catch {
          case _: NoSuchMethodException => None
        }

      // Invoke main() if it exists.
      mainMethod.foreach { method =>
        try method.invoke(this)
        catch {
          case e: InvocationTargetException => throw e.getCause
        }
      }
    }
    observe(PostMain) {
      for (f <- postmains.asScala) f()
    }

    observe(Close) {
      // We get a reference to the `close()` Future in order to Await upon it, to ensure the thread
      // waits for `close()` to complete.
      // Note that the Future returned here is the same as `promise` exposed via ClosableOnce,
      // which is the same result that would be returned by an `Await.result` on `this`.
      val closeFuture = close(defaultCloseGracePeriod)

      val waitForIt = (closeDeadline + SecondChanceGrace).sinceNow

      // No need to pass a timeout to Await, close(...) enforces the timeout for us.
      if (!suppressGracefulShutdownErrors) Await.result(closeFuture, waitForIt)
      else {
        try { // even if we suppress shutdown errors, we give the resources time to close
          Await.ready(closeFuture, waitForIt)
        } catch {
          case e: TimeoutException =>
            throw e // we want TimeoutExceptions to propagate
          case NonFatal(_) => ()
        }
      }
    }
  }