McServerTransaction::McServerTransaction( std::shared_ptr<McServerSession> session, McRequest&& request, mc_op_t operation, uint64_t reqid, bool isMultiget, bool isSubRequest, bool noreply) : session_(std::move(session)), request_(std::move(request)), operation_(operation), reqid_(reqid), appContext_(*this), noReply_(noreply || (operation == mc_op_quit)), isMultiget_(isMultiget), isSubRequest_(isSubRequest) { mc_msg_init_not_refcounted(&replyMsg_); um_backing_msg_init(&umMsg_); mc_ascii_response_buf_init(&asciiResponse_); assert(!(isMultiget_ && isSubRequest)); session_->onTransactionStarted(isSubRequest_); }
bool AsciiSerializedReply::prepare(const McReply& reply, mc_op_t operation, const folly::Optional<folly::IOBuf>& key, struct iovec*& iovOut, size_t& niovOut) { mc_msg_t replyMsg; mc_msg_init_not_refcounted(&replyMsg); reply.dependentMsg(operation, &replyMsg); nstring_t k; if (key.hasValue()) { k.str = (char*)key->data(); k.len = key->length(); } else { k.str = nullptr; k.len = 0; } niovOut = mc_ascii_response_write_iovs( &asciiResponse_, k, operation, &replyMsg, iovs_, kMaxIovs); iovOut = iovs_; return niovOut != 0; }
ssize_t um_consume_one_message(um_parser_t* um_parser, const uint8_t* buf, size_t nbuf, uint64_t* reqid_out, mc_msg_t** msg_out) { FBI_ASSERT(um_parser && buf && nbuf > 0 && reqid_out && msg_out); *msg_out = NULL; ssize_t consumed = entry_list_preparer_read(&um_parser->prep, (const char*)buf, nbuf); if (consumed <= 0) { goto error; } /* Because the rank of the unsigned integer is equal to the rank of the * signed integer, the signed integer is converted to the type of the * unsigned integer, and this assertion triggers on error. To get around * this, we do the cast ourselves. */ FBI_ASSERT(consumed <= (ssize_t)nbuf); if (entry_list_preparer_finished(&um_parser->prep)) { entry_list_t elist; if (entry_list_consume_preparer(&elist, &um_parser->prep) < 0) { goto error; } mc_msg_t base; mc_msg_init_not_refcounted(&base); _parse_info_t parse_info; if (_fill_base_msg(&elist, &base, &parse_info) != 0) { goto error; } *reqid_out = parse_info.reqid; *msg_out = _msg_create(&base, &elist, &parse_info); if (*msg_out == NULL) { dbg_error("msg_create failed"); goto error; } FBI_ASSERT((*msg_out)->op != mc_op_end); entry_list_cleanup(&elist); } else { FBI_ASSERT(consumed == nbuf); } return consumed; error: entry_list_preparer_reset_after_failure(&um_parser->prep); // Function that return an error must have not left any messages around FBI_ASSERT(*msg_out == NULL); return -1; }
TEST(umbrella, iovecSerialize) { size_t nIovs = 3; char value[] = "value"; iovec iovs[] = {{&value[0], 1}, {&value[1], 2}, {&value[3], 2}}; um_backing_msg_t bmsg; um_backing_msg_init(&bmsg); uint64_t reqId = 1; mc_msg_t msg; mc_msg_init_not_refcounted(&msg); msg.op = mc_op_get; msg.result = mc_res_found; msg.flags = 0x4; // Verify emitIov std::string serializedVal = ""; EXPECT_EQ( um_emit_iovs_extended( &bmsg, reqId, &msg, iovs, nIovs, emitIov, (void *)&serializedVal), 0); verifySerializedValue(serializedVal, reqId, &msg, value); // Verify writeIov um_backing_msg_cleanup(&bmsg); um_backing_msg_init(&bmsg); serializedVal = ""; reqId++; iovec output[20]; ssize_t nOutIovs = um_write_iovs_extended(&bmsg, reqId, &msg, iovs, nIovs, output, 20); EXPECT_GE(nOutIovs, 1); for (int i = 0; i < nOutIovs; i++) { serializedVal.append((const char *)output[i].iov_base, output[i].iov_len); } verifySerializedValue(serializedVal, reqId, &msg, value); }
WriteBuffer::WriteBuffer() { mc_msg_init_not_refcounted(&replyMsg_); um_backing_msg_init(&umMsg_); mc_ascii_response_buf_init(&asciiResponse_); }