void ProxyRequestContext::sendReply(McReply newReply) { if (recording_) { return; } if (replied_) { return; } reply_ = std::move(newReply); replied_ = true; if (LIKELY(enqueueReply_ != nullptr)) { fiber_local::runWithoutLocals([this]() { enqueueReply_(*this); }); } stat_incr(proxy_.stats, request_replied_stat, 1); stat_incr(proxy_.stats, request_replied_count_stat, 1); if (mc_res_is_err(reply_->result())) { stat_incr(proxy_.stats, request_error_stat, 1); stat_incr(proxy_.stats, request_error_count_stat, 1); } else { stat_incr(proxy_.stats, request_success_stat, 1); stat_incr(proxy_.stats, request_success_count_stat, 1); } }
void FailoverErrorsSettings::List::init(std::vector<std::string> errors) { failover_ = folly::make_unique<std::array<bool, mc_nres>>(); for (const auto& error : errors) { int i; for (i = 0; i < mc_nres; ++i) { mc_res_t errorType = static_cast<mc_res_t>(i); folly::StringPiece errorName(mc_res_to_string(errorType)); errorName.removePrefix("mc_res_"); if (mc_res_is_err(errorType) && error == errorName) { (*failover_)[i] = true; break; } } checkLogic(i < mc_nres, "Failover error '{}' is not a valid error type.", error); } }
size_t mc_ascii_response_write_iovs(mc_ascii_response_buf_t* buf, const mc_msg_t* req, const mc_msg_t* reply, struct iovec* iovs, size_t max_niovs) { size_t niovs = 0; buf->offset = 0; if (mc_res_is_err(reply->result)) { if (reply->value.len > 0) { if (reply->result == mc_res_client_error) { IOV_WRITE_CONST_STR("CLIENT_ERROR "); } else { IOV_WRITE_CONST_STR("SERVER_ERROR "); } if (reply->err_code != 0) { IOV_FORMAT(buf, "%" PRIu32 " ", reply->err_code); } IOV_WRITE_NSTRING(reply->value); IOV_WRITE_CONST_STR("\r\n"); } else { IOV_WRITE_STR(mc_res_to_response_string(reply->result)); } return niovs; } switch (req->op) { case mc_op_incr: case mc_op_decr: switch (reply->result) { case mc_res_stored: IOV_FORMAT(buf, "%" PRIu64 "\r\n", reply->delta); break; case mc_res_notfound: IOV_WRITE_CONST_STR("NOT_FOUND\r\n"); break; default: goto UNEXPECTED; } break; case mc_op_set: case mc_op_lease_set: case mc_op_add: case mc_op_replace: case mc_op_append: case mc_op_prepend: case mc_op_cas: switch (reply->result) { case mc_res_ok: IOV_WRITE_STR(mc_res_to_response_string(mc_res_stored)); break; case mc_res_stored: case mc_res_stalestored: case mc_res_found: case mc_res_notstored: case mc_res_notfound: case mc_res_exists: IOV_WRITE_STR(mc_res_to_response_string(reply->result)); break; default: goto UNEXPECTED; } break; case mc_op_delete: switch (reply->result) { case mc_res_deleted: case mc_res_notfound: IOV_WRITE_STR(mc_res_to_response_string(reply->result)); break; default: goto UNEXPECTED; } break; case mc_op_get: case mc_op_lease_get: case mc_op_gets: switch (reply->result) { case mc_res_found: IOV_WRITE_CONST_STR("VALUE "); IOV_WRITE_NSTRING(req->key); IOV_FORMAT(buf, " %" PRIu64 " %lu", reply->flags, reply->value.len); if (req->op == mc_op_gets) { IOV_FORMAT(buf, " %" PRIu64, reply->cas); } IOV_WRITE_CONST_STR("\r\n"); IOV_WRITE_NSTRING(reply->value); IOV_WRITE_CONST_STR("\r\n"); break; case mc_res_notfound: if (req->op != mc_op_lease_get) { // misses should have been suppressed! goto UNEXPECTED; } // but lease-get always has a response IOV_WRITE_CONST_STR("LVALUE "); IOV_WRITE_NSTRING(req->key); IOV_FORMAT(buf, " %" PRIu64 " %"PRIu64 " %zu\r\n", reply->lease_id, reply->flags, reply->value.len); IOV_WRITE_NSTRING(reply->value); IOV_WRITE_CONST_STR("\r\n"); break; default: goto UNEXPECTED; } break; case mc_op_metaget: switch (reply->result) { case mc_res_found: /* (META key age: (unknown|\d+); exptime: \d+; from: (\d+\.\d+\.\d+\.\d+|unknown); is_transient: (1|0)\r\n) */ IOV_WRITE_CONST_STR("META "); IOV_WRITE_NSTRING(req->key); IOV_WRITE_CONST_STR(" age: "); if (reply->number == (uint32_t) -1) { IOV_WRITE_CONST_STR("unknown"); } else { IOV_FORMAT(buf, "%d", reply->number); } IOV_WRITE_CONST_STR("; exptime: "); IOV_FORMAT(buf, "%d", reply->exptime); IOV_WRITE_CONST_STR("; from: "); if (reply->ipv == 0) { IOV_WRITE_CONST_STR("unknown"); } else { IOV_WRITE_IP(buf, reply->ipv, &(reply->ip_addr)); } IOV_WRITE_CONST_STR("; is_transient: "); IOV_FORMAT(buf, "%" PRIu64, reply->flags); IOV_WRITE_CONST_STR("\r\n"); break; case mc_res_notfound: break; default: goto UNEXPECTED; } break; case mc_op_end: if (reply->result == mc_res_found) { IOV_WRITE_CONST_STR("END\r\n"); } else { IOV_WRITE_STR(mc_res_to_response_string(reply->result)); } break; case mc_op_stats: switch (reply->result) { case mc_res_ok: { size_t length = 0; char* stats; if (reply->stats) { /* TODO(agartrell) assert(!reply->value.str) * * The assert here can't be turned on until * mcrouter/stats.c:560 has been fixed to not set both * value and stats on the libmc reply */ stats = stats_reply_to_string(reply->stats, reply->number, &length); buf->stats = stats; } else { stats = reply->value.str; length = reply->value.len; } if (!stats) { return 0; } IOV_WRITE(stats, length); break; } default: goto UNEXPECTED; } break; case mc_op_flushall: case mc_op_flushre: IOV_WRITE_CONST_STR("OK\r\n"); break; case mc_op_version: IOV_WRITE_CONST_STR("VERSION "); IOV_WRITE_NSTRING(reply->value); IOV_WRITE_CONST_STR("\r\n"); break; case mc_op_shutdown: if (reply->result == mc_res_ok) { IOV_WRITE_CONST_STR("OK\r\n"); } else { goto UNEXPECTED; } break; case mc_op_exec: switch (reply->result) { case mc_res_ok: IOV_WRITE_NSTRING(reply->value); IOV_WRITE_CONST_STR("\r\n"); break; default: goto UNEXPECTED; } break; default: IOV_WRITE_CONST_STR("SERVER_ERROR unhandled token "); IOV_WRITE_STR(mc_op_to_string(req->op)); IOV_FORMAT(buf, " (%d)\r\n", (int)req->op); break; } return niovs; UNEXPECTED: FBI_ASSERT(niovs == 0); IOV_WRITE_CONST_STR("SERVER_ERROR unexpected result "); IOV_WRITE_STR(mc_res_to_string(reply->result)); IOV_FORMAT(buf, " (%d) for ", (int)reply->result); IOV_WRITE_STR(mc_op_to_string(req->op)); IOV_FORMAT(buf, " (%d)\r\n", (int)req->op); return niovs; }
bool McReplyBase::isError() const { return mc_res_is_err(result_); }