Beispiel #1
0
ProxyRequestContext::ProxyRequestContext(
  proxy_t& pr,
  McMsgRef req,
  void (*enqReply)(ProxyRequestContext& preq),
  void* context,
  ProxyRequestPriority priority__,
  void (*reqComplete)(ProxyRequestContext& preq))
    : requestId_(pr.nextRequestId()),
      proxy_(pr),
      context_(context),
      enqueueReply_(enqReply),
      reqComplete_(reqComplete),
      priority_(priority__) {

  logger_.emplace(&proxy_);
  additionalLogger_.emplace(&proxy_);

  static const char* const kInternalGetPrefix = "__mcrouter__.";

  if (req->op == mc_op_get && !strncmp(req->key.str, kInternalGetPrefix,
                                       strlen(kInternalGetPrefix))) {
    /* HACK: for backwards compatibility, convert (get, "__mcrouter__.key")
       into (get-service-info, "key") */
    auto copy = MutableMcMsgRef(mc_msg_dup(req.get()));
    copy->op = mc_op_get_service_info;
    copy->key.str += strlen(kInternalGetPrefix);
    copy->key.len -= strlen(kInternalGetPrefix);
    origReq_ = std::move(copy);
  } else {
    origReq_ = std::move(req);
  }

  stat_incr_safe(proxy_.stats, proxy_request_num_outstanding_stat);
}
Beispiel #2
0
folly::IOBuf makeMsgIOBufStackHelper(const McMsgRef& msgRef) {
  if (!msgRef.get()) {
    return {};
  }
  auto msg = const_cast<mc_msg_t*>(msgRef.get());
  if (!(msg->*F).len) {
    return {};
  }
  return folly::IOBuf(
    folly::IOBuf::TAKE_OWNERSHIP,
    (msg->*F).str, (msg->*F).len, (msg->*F).len,
    [] (void* buf, void* ctx) {
      auto m = reinterpret_cast<mc_msg_t*>(ctx);
      mc_msg_decref(m);
    },
    mc_msg_incref(msg));
}
Beispiel #3
0
std::unique_ptr<folly::IOBuf> makeMsgIOBufHelper(const McMsgRef& msgRef,
                                                 bool returnEmpty) {
  if (!msgRef.get()) {
    return returnEmpty ? folly::IOBuf::create(0) : nullptr;
  }
  auto msg = const_cast<mc_msg_t*>(msgRef.get());
  if (!(msg->*F).len) {
    return returnEmpty ? folly::IOBuf::create(0) : nullptr;
  }
  return folly::IOBuf::takeOwnership(
    (msg->*F).str, (msg->*F).len, (msg->*F).len,
    [] (void* buf, void* ctx) {
      auto m = reinterpret_cast<mc_msg_t*>(ctx);
      mc_msg_decref(m);
    },
    mc_msg_incref(msg));
}
void McProtocolSerializer::RequestContext::serializeMcMsgUmbrella(
    const McMsgRef& req, size_t reqId) {
  // Umbrella serializer doesn't work with McMsgRef and it will need to
  // increment refcount.
  auto msg = const_cast<mc_msg_t*>(req.get());
  ssize_t r = um_write_iovs(&umBackingMsg_, reqId, msg, iovs_, kMaxIovs);
  if (r == -1) {
    iovsCount_ = 0;
  } else {
    iovsCount_ = r;
  }
}
void McProtocolSerializer::RequestContext::serializeMcMsgAscii(
    const McMsgRef& req) {
  // We need to ensure that this message lives as long as we have iovs.
  msg_ = req.clone();

  size_t hdrLength = mc_ascii_req_max_hdr_length(msg_.get());

  asciiBuffer_ = std::unique_ptr<char[]>(new char[hdrLength]);

  int r = mc_serialize_req_ascii(msg_.get(), asciiBuffer_.get(), hdrLength,
    iovs_, kMaxIovs);

  iovsCount_ = r < 0 ? 0 : r;
}
McProtocolSerializer::Result McProtocolSerializer::serialize(
    const McMsgRef& req, size_t reqId, RequestContext& ctx) const {
  if (!mc_client_req_is_valid(req.get()) ||
      (protocol_ == mc_ascii_protocol && req->key.len > MC_KEY_MAX_LEN_ASCII)) {
    return Result::BAD_KEY;
  }

  switch (protocol_) {
    case mc_ascii_protocol:
      ctx.serializeMcMsgAscii(req);
      break;
    case mc_umbrella_protocol:
      ctx.serializeMcMsgUmbrella(req, reqId);
      break;
    case mc_unknown_protocol:
    case mc_binary_protocol:
    case mc_nprotocols:
      // We already assert for them in constructor.
      ctx.iovsCount_ = 0;
  }
  return ctx.iovsCount_ != 0 ? Result::OK : Result::ERROR;
}