std::string FailoverWithExptimeRoute::keyWithFailoverTag( folly::StringPiece fullKey, const AccessPoint& ap) { const size_t tagLength = kFailoverTagStart.size() + ap.getHost().size() + 6; // 1 for kFailoverHostPortSeparator + 5 for port. std::string failoverTag; failoverTag.reserve(tagLength); failoverTag = kFailoverTagStart; failoverTag += ap.getHost().str(); if (ap.getPort() != 0) { failoverTag += kFailoverHostPortSeparator; failoverTag += folly::to<std::string>(ap.getPort()); } // Safety check: scrub the host and port for ':' to avoid appending // more than one field to the key. // Note: we start after the ':failover=' part of the string, // since we need the initial ':' and we know the remainder is safe. for (size_t i = kFailoverTagStart.size(); i < failoverTag.size(); i++) { if (failoverTag[i] == ':') { failoverTag[i] = '$'; } } return fullKey.str() + failoverTag; }
/** Adds an asynchronous request to the event log. */ void asynclog_delete(proxy_t* proxy, const AccessPoint& ap, folly::StringPiece key, folly::StringPiece poolName) { dynamic json = {}; const auto& host = ap.getHost(); const auto& port = proxy->router().opts().asynclog_port_override == 0 ? ap.getPort() : proxy->router().opts().asynclog_port_override; if (proxy->router().opts().use_asynclog_version2) { json = dynamic::object; json["f"] = proxy->router().opts().flavor_name; json["h"] = folly::sformat("[{}]:{}", host, port); json["p"] = poolName.str(); json["k"] = key.str(); } else { /* ["host", port, escaped_command] */ json.push_back(host); json.push_back(port); json.push_back(folly::sformat("delete {}\r\n", key)); } auto fd = asynclog_open(proxy); if (!fd) { MC_LOG_FAILURE(proxy->router().opts(), memcache::failure::Category::kSystemError, "asynclog_open() failed (key {}, pool {})", key, poolName); return; } // ["AS1.0", 1289416829.836, "C", ["10.0.0.1", 11302, "delete foo\r\n"]] // OR ["AS2.0", 1289416829.836, "C", {"f":"flavor","h":"[10.0.0.1]:11302", // "p":"pool_name","k":"foo\r\n"}] dynamic jsonOut = {}; if (proxy->router().opts().use_asynclog_version2) { jsonOut.push_back(ASYNCLOG_MAGIC2); } else { jsonOut.push_back(ASYNCLOG_MAGIC); } struct timeval timestamp; CHECK(gettimeofday(×tamp, nullptr) == 0); auto timestamp_ms = facebook::memcache::to<std::chrono::milliseconds>(timestamp).count(); jsonOut.push_back(1e-3 * timestamp_ms); jsonOut.push_back(std::string("C")); jsonOut.push_back(json); auto jstr = folly::toJson(jsonOut) + "\n"; ssize_t size = folly::writeFull(fd->fd(), jstr.data(), jstr.size()); if (size == -1 || size_t(size) < jstr.size()) { MC_LOG_FAILURE(proxy->router().opts(), memcache::failure::Category::kSystemError, "Error fully writing asynclog request (key {}, pool {})", key, poolName); } }