コード例 #1
0
ファイル: van.cpp プロジェクト: lacozhang/numopt
bool Van::send(Message *msg, size_t *sendBytes) {
  CHECK_NOTNULL(msg);
  CHECK_NOTNULL(sendBytes);

  NodeID recverId = msg->recver_;
  auto it = senders_.find(recverId);
  if (it == senders_.end()) {
    LOG(WARNING) << "There is no socket to node " << recverId;
    return false;
  }
  void *socket = it->second;

  bool has_key = !msg->key_.empty();
  if (has_key) {
    msg->task_.set_has_key(has_key);
  } else {
    msg->task_.clear_has_key();
  }
  int n = has_key + msg->value_.size();
  size_t dataSize = 0;

  size_t taskSize = msg->task_.ByteSize();
  char *taskBuff = new char[taskSize + 5];
  std::memset(taskBuff, 0, taskSize + 5);
  if (taskBuff == nullptr) {
    LOG(FATAL) << "Failed to allocate memory";
  }
  CHECK(msg->task_.SerializeToArray(taskBuff, taskSize))
      << "failed to serialize task " << msg->task_.ShortDebugString();

  int tag = ZMQ_SNDMORE;
  if (n == 0) {
    tag = 0;
  }
  zmq_msg_t taskMsg;
  zmq_msg_init_data(&taskMsg, taskBuff, taskSize, freeData, nullptr);
  while (true) {
    if (zmq_msg_send(&taskMsg, socket, tag) == taskSize) {
      break;
    }
    if (errno == EINTR) {
      continue;
    }
    LOG(WARNING) << "failed to send to node " << recverId
                 << zmq_strerror(errno);
    return false;
  }
  dataSize += taskSize;

  for (int i = 0; i < n; ++i) {
    DArray<char> *data = new DArray<char>(
        (i == 0 && has_key) ? msg->key_ : msg->value_[i - has_key]);
    if (data == nullptr) {
      LOG(ERROR) << "Failed to allocate memory";
      return false;
    }
    zmq_msg_t dataMsg;
    zmq_msg_init_data(&dataMsg, data->data(), data->size(), freeData, data);
    if (i == n - 1) {
      tag = 0;
    }
    while (true) {
      if (zmq_msg_send(&dataMsg, socket, tag) == data->size()) {
        break;
      }
      if (errno == EINTR) {
        continue;
      }
      LOG(WARNING) << "failed to send data to " << recverId
                   << " errno : " << zmq_strerror(errno);
      return false;
    }
    dataSize += data->size();
  }

  *sendBytes += dataSize;
  if (hostnames_[recverId] == myNode_.hostname()) {
    sentToLocal_ += dataSize;
  } else {
    sentToOthers_ += dataSize;
  }
  VLOG(1) << "To " << msg->recver_ << " " << msg->ShortDebugString();
  return true;
}