示例#1
0
void McServerTransaction::onMultigetReply(McReply& subReply) {
    assert(isMultiget_);

    /* If not a hit or a miss, and we didn't store a reply yet,
       steal it */
    if (!(subReply.result() == mc_res_found ||
            subReply.result() == mc_res_notfound) &&
            (!reply_.hasValue() ||
             (subReply.result() > reply_->result()))) {
        reply_ = std::move(subReply);
    }

    assert(numMultiget_ > 0);
    --numMultiget_;

    if (!numMultiget_) {
        if (!reply_.hasValue()) {
            reply_ = McReply(mc_res_found);
        }
        replyReady_ = true;
        session_->onRequestReplied(*this);
    }
}
示例#2
0
bool UmbrellaSerializedMessage::prepare(const McReply& reply, mc_op_t op,
                                        uint64_t reqid, struct iovec*& iovOut,
                                        size_t& niovOut) {
  niovOut = 0;

  appendInt(I32, msg_op, umbrella_op_from_mc[op]);
  appendInt(U64, msg_reqid, reqid);
  appendInt(I32, msg_result, umbrella_res_from_mc[reply.result()]);

  if (reply.appSpecificErrorCode()) {
    appendInt(I32, msg_err_code, reply.appSpecificErrorCode());
  }
  if (reply.flags()) {
    appendInt(U64, msg_flags, reply.flags());
  }
  if (reply.exptime()) {
    appendInt(U64, msg_exptime, reply.exptime());
  }
  if (reply.delta()) {
    appendInt(U64, msg_delta, reply.delta());
  }
  if (reply.leaseToken()) {
    appendInt(U64, msg_lease_id, reply.leaseToken());
  }
  if (reply.cas()) {
    appendInt(U64, msg_cas, reply.cas());
  }
  if (reply.number()) {
    appendInt(U64, msg_number, reply.number());
  }

  /* TODO: if we intend to pass chained IOBufs as values,
     we can optimize this to write multiple iovs directly */
  if (reply.hasValue()) {
    auto valueRange = reply.valueRangeSlow();
    appendString(msg_value,
                 reinterpret_cast<const uint8_t*>(valueRange.begin()),
                 valueRange.size());
  }

  /* NOTE: this check must come after all append*() calls */
  if (error_) {
    return false;
  }

  niovOut = finalizeMessage();
  iovOut = iovs_;
  return true;
}
bool McServerRequestContext::noReply(const McReply& reply) const {
  if (noReply_) {
    return true;
  }

  if (!parent_) {
    return false;
  }

  /* No reply if either:
     1) We saw an error (the error will be printed out by the end context)
     2) This is a miss, except for lease_get (lease get misses still have
     'LVALUE' replies with the token) */
  return (parent_->error() ||
          !(reply.result() == mc_res_found ||
            operation_ == mc_op_lease_get));
}
示例#4
0
void DestinationClient::onReply(McReply reply, mc_op_t op, void* req_ctx,
                                std::weak_ptr<ProxyDestination> pdstn) {
  auto pdstnPtr = pdstn.lock();
  // ProxyDestination is already dead, just return.
  if (!pdstnPtr) {
    return;
  }
  auto proxy = pdstnPtr->proxy;

  if (reply.result() == mc_res_local_error) {
    update_send_stats(proxy, op, PROXY_SEND_LOCAL_ERROR);
  } else {
    stat_incr(proxy->stats, sum_server_queue_length_stat, 1);
    update_send_stats(proxy, op, PROXY_SEND_OK);
  }

  pdstnPtr->on_reply(std::move(reply),
                     req_ctx);
}
bool UmbrellaSerializedReply::prepare(const McReply& reply,
                                      mc_op_t op, uint64_t reqid,
                                      struct iovec*& iovOut, size_t& niovOut) {
  static char nul = '\0';

  /* We can reuse this struct multiple times, reset the counters */
  nEntries_ = nStrings_ = offset_ = 0;
  error_ = false;
  niovOut = 0;

  appendInt(I32, msg_op, umbrella_op_from_mc[op]);
  appendInt(U64, msg_reqid, reqid);
  appendInt(I32, msg_result, umbrella_res_from_mc[reply.result()]);

  if (reply.appSpecificErrorCode()) {
    appendInt(I32, msg_err_code, reply.appSpecificErrorCode());
  }
  if (reply.flags()) {
    appendInt(U64, msg_flags, reply.flags());
  }
  if (reply.exptime()) {
    appendInt(U64, msg_exptime, reply.exptime());
  }
  if (reply.delta()) {
    appendInt(U64, msg_delta, reply.delta());
  }
  if (reply.leaseToken()) {
    appendInt(U64, msg_lease_id, reply.leaseToken());
  }
  if (reply.cas()) {
    appendInt(U64, msg_cas, reply.cas());
  }
  if (reply.lowValue() || reply.highValue()) {
    appendDouble(reply.lowValue());
  }
  if (reply.highValue()) {
    appendDouble(reply.highValue());
  }

  /* TODO: if we intend to pass chained IOBufs as values,
     we can optimize this to write multiple iovs directly */
  if (reply.hasValue()) {
    auto valueRange = reply.valueRangeSlow();
    appendString(msg_value,
                 reinterpret_cast<const uint8_t*>(valueRange.begin()),
                 valueRange.size());
  }

  /* NOTE: this check must come after all append*() calls */
  if (error_) {
    return false;
  }

  size_t size = sizeof(entry_list_msg_t) +
    sizeof(um_elist_entry_t) * nEntries_ +
    offset_;

  msg_.total_size = folly::Endian::big((uint32_t)size);
  msg_.nentries = folly::Endian::big((uint16_t)nEntries_);

  iovs_[1].iov_len = sizeof(um_elist_entry_t) * nEntries_;
  niovOut = 2;

  for (size_t i = 0; i < nStrings_; i++) {
    iovs_[niovOut].iov_base = (char *)strings_[i].begin();
    iovs_[niovOut].iov_len = strings_[i].size();
    niovOut++;

    iovs_[niovOut].iov_base = &nul;
    iovs_[niovOut].iov_len = 1;
    niovOut++;
  }

  iovOut = iovs_;
  return true;
}