bool runServer()

in mcrouter/Server-inl.h [485:587]


bool runServer(
    const McrouterOptions& mcrouterOpts,
    const McrouterStandaloneOptions& standaloneOpts,
    StandalonePreRunCb preRunCb) {
  AsyncMcServer::Options opts =
      detail::createAsyncMcServerOptions(mcrouterOpts, standaloneOpts);

  std::shared_ptr<folly::IOThreadPoolExecutor> ioThreadPool;
  CarbonRouterInstance<RouterInfo>* router = nullptr;
  std::shared_ptr<AsyncMcServer> asyncMcServer;
  try {
    LOG(INFO) << "Spawning AsyncMcServer";
    // Create thread pool for both AsyncMcServer and CarbonRouterInstance
    ioThreadPool = std::make_shared<folly::IOThreadPoolExecutor>(
        mcrouterOpts.num_proxies, mcrouterOpts.num_proxies);

    // Run observer and extract event bases
    auto executorObserver = std::make_shared<ExecutorObserver>();
    ioThreadPool->addObserver(executorObserver);
    auto evbs = executorObserver->extractEvbs();
    CHECK_EQ(evbs.size(), mcrouterOpts.num_proxies);
    ioThreadPool->removeObserver(executorObserver);

    // Get EVB of main thread
    auto localEvb = ioThreadPool->getEventBaseManager()->getEventBase();

    asyncMcServer =
        std::make_shared<AsyncMcServer>(detail::createAsyncMcServerOptions(
            mcrouterOpts, standaloneOpts, &evbs));

    if (standaloneOpts.remote_thread) {
      router =
          CarbonRouterInstance<RouterInfo>::init("standalone", mcrouterOpts);
    } else {
      router = CarbonRouterInstance<RouterInfo>::init(
          "standalone", mcrouterOpts, ioThreadPool);
    }
    if (router == nullptr) {
      LOG(ERROR) << "CRITICAL: Failed to initialize mcrouter!";
      return false;
    }

    setupRouter<RouterInfo>(mcrouterOpts, standaloneOpts, router, preRunCb);

    auto shutdownStarted = std::make_shared<std::atomic<bool>>(false);
    ShutdownSignalHandler<RouterInfo> shutdownHandler(
        localEvb, nullptr, asyncMcServer, shutdownStarted);
    shutdownHandler.registerSignalHandler(SIGTERM);
    shutdownHandler.registerSignalHandler(SIGINT);

    // Create CarbonRouterClients for each worker thread
    std::vector<typename CarbonRouterClient<RouterInfo>::Pointer>
        carbonRouterClients;
    for (size_t i = 0; i < mcrouterOpts.num_proxies; i++) {
      // Create CarbonRouterClients
      auto routerClient = standaloneOpts.remote_thread
          ? router->createClient(0 /* maximum_outstanding_requests */)
          : router->createSameThreadClient(
                0 /* maximum_outstanding_requests */);
      carbonRouterClients.push_back(std::move(routerClient));
    }
    CHECK_EQ(carbonRouterClients.size(), mcrouterOpts.num_proxies);

    auto aclChecker = detail::getAclChecker(mcrouterOpts, standaloneOpts);
    asyncMcServer->startOnVirtualEB(
        [&router,
         &carbonRouterClients,
         &standaloneOpts,
         aclChecker = aclChecker](
            size_t threadId,
            folly::VirtualEventBase& vevb,
            AsyncMcServerWorker& worker) mutable {
          detail::serverInit<RouterInfo, RequestHandler>(
              *router,
              threadId,
              vevb.getEventBase(),
              worker,
              standaloneOpts,
              aclChecker,
              carbonRouterClients[threadId].get());
        },
        [evb = localEvb, &asyncMcServer, &shutdownStarted] {
          evb->runInEventBaseThread([&]() {
            detail::startServerShutdown<RouterInfo>(
                nullptr, asyncMcServer, shutdownStarted);
          });
          evb->terminateLoopSoon();
        });
    localEvb->loopForever();
    LOG(INFO) << "Started shutdown of CarbonRouterInstance";
    router->shutdown();
    freeAllRouters();
    ioThreadPool.reset();
    if (!opts.unixDomainSockPath.empty()) {
      std::remove(opts.unixDomainSockPath.c_str());
    }
    LOG(INFO) << "Completed shutdown";
  } catch (const std::exception& e) {
    LOG(ERROR) << e.what();
    exit(EXIT_FAILURE);
  }
  return true;
}