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;
}