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_);
  }
}
Beispiel #2
0
void AsyncMcServer::shutdown() {
  if (!alive_.exchange(false)) {
    return;
  }

  if (onShutdown_) {
    onShutdown_();
  }

  for (auto& thread : threads_) {
    thread->shutdown();
  }
}