void McServerSession::requestReady(McRequest req, mc_op_t operation, uint64_t reqid, mc_res_t result, bool noreply) { DestructorGuard dg(this); auto sharedThis = weakThis_.lock(); if (!sharedThis) { /* This session is being destroyed, can't create new transactions */ close(); return; } if (state_ != STREAMING) { return; } auto isSubRequest = isPartOfMultiget(parser_.protocol(), operation); auto isMultiget = (operation == mc_op_end); auto transactionPtr = folly::make_unique<McServerTransaction>( sharedThis, std::move(req), operation, reqid, isMultiget, isSubRequest, noreply); McServerTransaction& transaction = [&]() -> McServerTransaction& { if (isSubRequest) { return multigetRequests_.pushBack(std::move(transactionPtr)); } else { return unansweredRequests_.pushBack(std::move(transactionPtr)); } }(); if (result == mc_res_bad_key) { transaction.sendReply(McReply(mc_res_bad_key)); } else if (operation == mc_op_version) { transaction.sendReply(McReply(mc_res_ok, options_.versionString)); } else if (operation == mc_op_quit) { /* mc_op_quit transaction will have `noreply` set, so this call is solely to make sure the transaction is completed and cleaned up */ transaction.sendReply(McReply(mc_res_ok)); close(); } else if (operation == mc_op_shutdown) { transaction.sendReply(McReply(mc_res_ok)); onShutdown_(); } else if (isMultiget) { while (!multigetRequests_.empty()) { auto subReq = multigetRequests_.popFront(); transaction.pushMultigetRequest(std::move(subReq)); } transaction.dispatchSubRequests(*onRequest_); } else if (!isSubRequest) { transaction.dispatchRequest(*onRequest_); } }
void AsyncMcServer::shutdown() { if (!alive_.exchange(false)) { return; } if (onShutdown_) { onShutdown_(); } for (auto& thread : threads_) { thread->shutdown(); } }