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; }