示例#1
0
size_t McrouterClient::send(
  const mcrouter_msg_t* requests,
  size_t nreqs,
  folly::StringPiece ipAddr /* = folly::StringPiece() */ ) {

  assert(!disconnected_);

  if (nreqs == 0) {
    return 0;
  }

  size_t id = 0;
  auto makeNextPreq = [this, requests, &id, ipAddr]() {
    auto cb = [
      this,
      context = requests[id].context,
      req = McMsgRef::cloneRef(requests[id].req)
    ](ProxyRequestContext&, McReply&& reply) mutable {
      this->onReply(std::move(reply), std::move(req), context);
    };
    auto preq = createLegacyProxyRequestContext(
        *proxy_, McMsgRef::cloneRef(requests[id].req), std::move(cb));
    preq->requester_ = self_;

    if (!ipAddr.empty()) {
      preq->setUserIpAddress(ipAddr);
    }
    ++id;
    return preq;
  };

  auto cancelRemaining = [this, requests, &id, nreqs]() {
    for (; id < nreqs; ++id) {
      mcrouter_msg_t error_reply;
      error_reply.req = requests[id].req;
      error_reply.reply = McReply(mc_res_local_error);
      error_reply.context = requests[id].context;

      callbacks_.on_reply(&error_reply, arg_);
    }
  };

  auto res =
      sendMultiImpl(nreqs, std::move(makeNextPreq), std::move(cancelRemaining));
  return res ? nreqs : 0;
}
示例#2
0
size_t McrouterClient::send(
  const mcrouter_msg_t* requests,
  size_t nreqs,
  folly::StringPiece ipAddr /* = folly::StringPiece() */ ) {

  assert(!disconnected_);

  auto router = router_.lock();
  if (nreqs == 0 || !router) {
    return 0;
  }

  auto makePreq = [this, &requests, ipAddr](size_t i) {
    auto cb =
      [this, context = requests[i].context,
       req = McMsgRef::cloneRef(requests[i].req)]
      (ProxyRequestContext&, McReply&& reply) mutable {
        this->onReply(std::move(reply), std::move(req), context);
      };
    auto preq = createLegacyProxyRequestContext(
        *proxy_, McMsgRef::cloneRef(requests[i].req), std::move(cb));
    preq->requester_ = self_;

    if (!ipAddr.empty()) {
      preq->setUserIpAddress(ipAddr);
    }
    return preq;
  };

  if (maxOutstanding_ == 0) {
    if (sameThread_) {
      for (size_t i = 0; i < nreqs; i++) {
        sendSameThread(makePreq(i));
      }
    } else {
      for (size_t i = 0; i < nreqs; i++) {
        sendRemoteThread(makePreq(i));
      }
    }
  } else if (maxOutstandingError_) {
    for(size_t begin = 0; begin < nreqs;) {
      auto end = begin + counting_sem_lazy_nonblocking(&outstandingReqsSem_,
                                                       nreqs - begin);
      if (begin == end) {
        for (size_t i = begin; i < nreqs; ++i) {
          mcrouter_msg_t error_reply;
          error_reply.req = requests[i].req;
          error_reply.reply = McReply(mc_res_local_error);
          error_reply.context = requests[i].context;

          callbacks_.on_reply(&error_reply, arg_);
        }

        break;
      }

      if (sameThread_) {
        for (size_t i = begin; i < end; i++) {
          sendSameThread(makePreq(i));
        }
      } else {
        for (size_t i = begin; i < end; i++) {
          sendRemoteThread(makePreq(i));
        }
      }

      begin = end;
    }
  } else {
    assert(!sameThread_);

    size_t i = 0;
    size_t n = 0;

    while (i < nreqs) {
      n += counting_sem_lazy_wait(&outstandingReqsSem_, nreqs - n);
      for (size_t j = i; j < n; ++j) {
        sendRemoteThread(makePreq(j));
      }

      i = n;
    }
  }

  return nreqs;
}