mirror of
https://github.com/Icinga/icinga2.git
synced 2026-02-18 18:19:13 -05:00
Merge cfc55322fb into 333534096e
This commit is contained in:
commit
6fe989b390
7 changed files with 113 additions and 41 deletions
|
|
@ -22,6 +22,10 @@ String::String(const char *data)
|
|||
: m_Data(data)
|
||||
{ }
|
||||
|
||||
String::String(const std::string_view& data)
|
||||
: m_Data(data)
|
||||
{ }
|
||||
|
||||
String::String(std::string data)
|
||||
: m_Data(std::move(data))
|
||||
{ }
|
||||
|
|
@ -140,6 +144,16 @@ String::operator boost::beast::string_view() const
|
|||
return boost::beast::string_view(m_Data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion function to std::string_view.
|
||||
*
|
||||
* @return An std::string_view representing this string.
|
||||
*/
|
||||
String::operator std::string_view() const
|
||||
{
|
||||
return std::string_view(m_Data);
|
||||
}
|
||||
|
||||
const char *String::CStr() const
|
||||
{
|
||||
return m_Data.c_str();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <boost/utility/string_view.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace icinga {
|
||||
|
|
@ -42,6 +43,7 @@ public:
|
|||
|
||||
String() = default;
|
||||
String(const char *data);
|
||||
String(const std::string_view& data);
|
||||
String(std::string data);
|
||||
String(String::SizeType n, char c);
|
||||
String(const String& other);
|
||||
|
|
@ -76,6 +78,7 @@ public:
|
|||
|
||||
operator const std::string&() const;
|
||||
operator boost::beast::string_view() const;
|
||||
operator std::string_view() const;
|
||||
|
||||
const char *CStr() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -272,12 +272,12 @@ void IcingaDB::UpdateAllConfigObjects()
|
|||
String configObject = m_PrefixConfigObject + lcType;
|
||||
|
||||
// Skimmed away attributes and checksums HMSETs' keys and values by Redis key.
|
||||
std::map<String, std::vector<std::vector<String>>> ourContentRaw {{configCheckSum, {}}, {configObject, {}}};
|
||||
std::map<String, RedisConnection::Queries> ourContentRaw {{configCheckSum, {}}, {configObject, {}}};
|
||||
std::mutex ourContentMutex;
|
||||
|
||||
upqObjectType.ParallelFor(objectChunks, [&](decltype(objectChunks)::const_reference chunk) {
|
||||
std::map<String, std::vector<String>> hMSets;
|
||||
std::vector<String> hostZAdds = {"ZADD", "icinga:nextupdate:host"}, serviceZAdds = {"ZADD", "icinga:nextupdate:service"};
|
||||
std::map<String, RedisConnection::Query> hMSets;
|
||||
RedisConnection::Query hostZAdds = {"ZADD", "icinga:nextupdate:host"}, serviceZAdds = {"ZADD", "icinga:nextupdate:service"};
|
||||
|
||||
auto skimObjects ([&]() {
|
||||
std::lock_guard<std::mutex> l (ourContentMutex);
|
||||
|
|
@ -343,7 +343,7 @@ void IcingaDB::UpdateAllConfigObjects()
|
|||
zAdds->emplace_back(GetObjectIdentifier(checkable));
|
||||
|
||||
if (zAdds->size() >= 102u) {
|
||||
std::vector<String> header (zAdds->begin(), zAdds->begin() + 2u);
|
||||
RedisConnection::Query header (zAdds->begin(), zAdds->begin() + 2u);
|
||||
|
||||
rcon->FireAndForgetQuery(std::move(*zAdds), Prio::CheckResult);
|
||||
|
||||
|
|
@ -384,7 +384,15 @@ void IcingaDB::UpdateAllConfigObjects()
|
|||
upqObjectType.Enqueue([&]() {
|
||||
for (auto& hMSet : source.second) {
|
||||
for (decltype(hMSet.size()) i = 0, stop = hMSet.size() - 1u; i < stop; i += 2u) {
|
||||
dest.emplace(std::move(hMSet[i]), std::move(hMSet[i + 1u]));
|
||||
auto variantToString = [](RedisConnection::QueryArg v) -> String {
|
||||
if (auto str (std::get_if<String>(&v.GetData())); str) {
|
||||
return std::move(*str);
|
||||
}
|
||||
|
||||
return std::get<std::string_view>(v.GetData());
|
||||
};
|
||||
|
||||
dest.emplace(variantToString(std::move(hMSet[i])), variantToString(std::move(hMSet[i + 1u])));
|
||||
}
|
||||
|
||||
hMSet.clear();
|
||||
|
|
@ -399,7 +407,7 @@ void IcingaDB::UpdateAllConfigObjects()
|
|||
|
||||
auto& ourCheckSums (ourContent[configCheckSum]);
|
||||
auto& ourObjects (ourContent[configObject]);
|
||||
std::vector<String> setChecksum, setObject, delChecksum, delObject;
|
||||
RedisConnection::Query setChecksum, setObject, delChecksum, delObject;
|
||||
|
||||
auto redisCurrent (redisCheckSums.begin());
|
||||
auto redisEnd (redisCheckSums.end());
|
||||
|
|
@ -412,12 +420,12 @@ void IcingaDB::UpdateAllConfigObjects()
|
|||
setChecksum.insert(setChecksum.begin(), {"HMSET", configCheckSum});
|
||||
setObject.insert(setObject.begin(), {"HMSET", configObject});
|
||||
|
||||
std::vector<std::vector<String>> transaction;
|
||||
RedisConnection::Queries transaction;
|
||||
|
||||
transaction.emplace_back(std::vector<String>{"MULTI"});
|
||||
transaction.emplace_back(RedisConnection::Query{"MULTI"});
|
||||
transaction.emplace_back(std::move(setChecksum));
|
||||
transaction.emplace_back(std::move(setObject));
|
||||
transaction.emplace_back(std::vector<String>{"EXEC"});
|
||||
transaction.emplace_back(RedisConnection::Query{"EXEC"});
|
||||
|
||||
setChecksum.clear();
|
||||
setObject.clear();
|
||||
|
|
@ -431,12 +439,12 @@ void IcingaDB::UpdateAllConfigObjects()
|
|||
delChecksum.insert(delChecksum.begin(), {"HDEL", configCheckSum});
|
||||
delObject.insert(delObject.begin(), {"HDEL", configObject});
|
||||
|
||||
std::vector<std::vector<String>> transaction;
|
||||
RedisConnection::Queries transaction;
|
||||
|
||||
transaction.emplace_back(std::vector<String>{"MULTI"});
|
||||
transaction.emplace_back(RedisConnection::Query{"MULTI"});
|
||||
transaction.emplace_back(std::move(delChecksum));
|
||||
transaction.emplace_back(std::move(delObject));
|
||||
transaction.emplace_back(std::vector<String>{"EXEC"});
|
||||
transaction.emplace_back(RedisConnection::Query{"EXEC"});
|
||||
|
||||
delChecksum.clear();
|
||||
delObject.clear();
|
||||
|
|
@ -564,7 +572,7 @@ std::vector<std::vector<intrusive_ptr<ConfigObject>>> IcingaDB::ChunkObjects(std
|
|||
}
|
||||
|
||||
void IcingaDB::DeleteKeys(const RedisConnection::Ptr& conn, const std::vector<String>& keys, RedisConnection::QueryPriority priority) {
|
||||
std::vector<String> query = {"DEL"};
|
||||
RedisConnection::Query query = {"DEL"};
|
||||
for (auto& key : keys) {
|
||||
query.emplace_back(key);
|
||||
}
|
||||
|
|
@ -636,7 +644,7 @@ static ConfigObject::Ptr GetObjectByName(const String& name)
|
|||
return ConfigObject::GetObject<ConfigType>(name);
|
||||
}
|
||||
|
||||
void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const String typeName, std::map<String, std::vector<String>>& hMSets,
|
||||
void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const String typeName, std::map<String, RedisConnection::Query>& hMSets,
|
||||
std::vector<Dictionary::Ptr>& runtimeUpdates, bool runtimeUpdate)
|
||||
{
|
||||
String objectKey = GetObjectIdentifier(object);
|
||||
|
|
@ -692,12 +700,12 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
|||
auto id (HashValue(new Array({m_EnvironmentId, actionUrl})));
|
||||
|
||||
if (runtimeUpdate || m_DumpedGlobals.ActionUrl.IsNew(id)) {
|
||||
actionUrls.emplace_back(std::move(id));
|
||||
actionUrls.emplace_back(id);
|
||||
Dictionary::Ptr data = new Dictionary({{"environment_id", m_EnvironmentId}, {"action_url", actionUrl}});
|
||||
actionUrls.emplace_back(JsonEncode(data));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, actionUrls.at(actionUrls.size() - 2u), m_PrefixConfigObject + "action:url", data);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, id, m_PrefixConfigObject + "action:url", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -707,12 +715,12 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
|||
auto id (HashValue(new Array({m_EnvironmentId, notesUrl})));
|
||||
|
||||
if (runtimeUpdate || m_DumpedGlobals.NotesUrl.IsNew(id)) {
|
||||
notesUrls.emplace_back(std::move(id));
|
||||
notesUrls.emplace_back(id);
|
||||
Dictionary::Ptr data = new Dictionary({{"environment_id", m_EnvironmentId}, {"notes_url", notesUrl}});
|
||||
notesUrls.emplace_back(JsonEncode(data));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, notesUrls.at(notesUrls.size() - 2u), m_PrefixConfigObject + "notes:url", data);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, id, m_PrefixConfigObject + "notes:url", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -722,12 +730,12 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
|||
auto id (HashValue(new Array({m_EnvironmentId, iconImage})));
|
||||
|
||||
if (runtimeUpdate || m_DumpedGlobals.IconImage.IsNew(id)) {
|
||||
iconImages.emplace_back(std::move(id));
|
||||
iconImages.emplace_back(id);
|
||||
Dictionary::Ptr data = new Dictionary({{"environment_id", m_EnvironmentId}, {"icon_image", iconImage}});
|
||||
iconImages.emplace_back(JsonEncode(data));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, iconImages.at(iconImages.size() - 2u), m_PrefixConfigObject + "icon:image", data);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, id, m_PrefixConfigObject + "icon:image", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1334,7 +1342,7 @@ void IcingaDB::UpdateState(const Checkable::Ptr& checkable, StateUpdate mode)
|
|||
if (mode & StateUpdate::RuntimeOnly) {
|
||||
ObjectLock olock(stateAttrs);
|
||||
|
||||
std::vector<String> streamadd({
|
||||
RedisConnection::Query streamadd({
|
||||
"XADD", "icinga:runtime:state", "MAXLEN", "~", "1000000", "*",
|
||||
"runtime_type", "upsert",
|
||||
"redis_key", redisStateKey,
|
||||
|
|
@ -1467,7 +1475,7 @@ void IcingaDB::SendConfigUpdate(const ConfigObject::Ptr& object, bool runtimeUpd
|
|||
|
||||
String typeName = GetLowerCaseTypeNameDB(object);
|
||||
|
||||
std::map<String, std::vector<String>> hMSets;
|
||||
std::map<String, RedisConnection::Query> hMSets;
|
||||
std::vector<Dictionary::Ptr> runtimeUpdates;
|
||||
|
||||
CreateConfigUpdate(object, typeName, hMSets, runtimeUpdates, runtimeUpdate);
|
||||
|
|
@ -1807,7 +1815,7 @@ bool IcingaDB::PrepareObject(const ConfigObject::Ptr& object, Dictionary::Ptr& a
|
|||
* icinga:config:object:downtime) need to be prepended. There is nothing to indicate success or failure.
|
||||
*/
|
||||
void
|
||||
IcingaDB::CreateConfigUpdate(const ConfigObject::Ptr& object, const String typeName, std::map<String, std::vector<String>>& hMSets,
|
||||
IcingaDB::CreateConfigUpdate(const ConfigObject::Ptr& object, const String typeName, std::map<String, RedisConnection::Query>& hMSets,
|
||||
std::vector<Dictionary::Ptr>& runtimeUpdates, bool runtimeUpdate)
|
||||
{
|
||||
/* TODO: This isn't essentially correct as we don't keep track of config objects ourselves. This would avoid duplicated config updates at startup.
|
||||
|
|
@ -1969,7 +1977,7 @@ void IcingaDB::SendStateChange(const ConfigObject::Ptr& object, const CheckResul
|
|||
Array::Ptr rawId = new Array({m_EnvironmentId, object->GetName()});
|
||||
rawId->Add(eventTs);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:state", "*",
|
||||
"id", HashValue(rawId),
|
||||
"environment_id", m_EnvironmentId,
|
||||
|
|
@ -2054,7 +2062,7 @@ void IcingaDB::SendSentNotification(
|
|||
|
||||
auto notificationHistoryId (HashValue(rawId));
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:notification", "*",
|
||||
"id", notificationHistoryId,
|
||||
"environment_id", m_EnvironmentId,
|
||||
|
|
@ -2118,7 +2126,7 @@ void IcingaDB::SendStartedDowntime(const Downtime::Ptr& downtime)
|
|||
/* Update checkable state as in_downtime may have changed. */
|
||||
UpdateState(checkable, StateUpdate::Full);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:downtime", "*",
|
||||
"downtime_id", GetObjectIdentifier(downtime),
|
||||
"environment_id", m_EnvironmentId,
|
||||
|
|
@ -2207,7 +2215,7 @@ void IcingaDB::SendRemovedDowntime(const Downtime::Ptr& downtime)
|
|||
/* Update checkable state as in_downtime may have changed. */
|
||||
UpdateState(checkable, StateUpdate::Full);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:downtime", "*",
|
||||
"downtime_id", GetObjectIdentifier(downtime),
|
||||
"environment_id", m_EnvironmentId,
|
||||
|
|
@ -2293,7 +2301,7 @@ void IcingaDB::SendAddedComment(const Comment::Ptr& comment)
|
|||
Service::Ptr service;
|
||||
tie(host, service) = GetHostService(checkable);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:comment", "*",
|
||||
"comment_id", GetObjectIdentifier(comment),
|
||||
"environment_id", m_EnvironmentId,
|
||||
|
|
@ -2365,7 +2373,7 @@ void IcingaDB::SendRemovedComment(const Comment::Ptr& comment)
|
|||
Service::Ptr service;
|
||||
tie(host, service) = GetHostService(checkable);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:comment", "*",
|
||||
"comment_id", GetObjectIdentifier(comment),
|
||||
"environment_id", m_EnvironmentId,
|
||||
|
|
@ -2428,7 +2436,7 @@ void IcingaDB::SendFlappingChange(const Checkable::Ptr& checkable, double change
|
|||
Service::Ptr service;
|
||||
tie(host, service) = GetHostService(checkable);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:flapping", "*",
|
||||
"environment_id", m_EnvironmentId,
|
||||
"host_id", GetObjectIdentifier(host),
|
||||
|
|
@ -2525,7 +2533,7 @@ void IcingaDB::SendAcknowledgementSet(const Checkable::Ptr& checkable, const Str
|
|||
/* Update checkable state as is_acknowledged may have changed. */
|
||||
UpdateState(checkable, StateUpdate::Full);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:acknowledgement", "*",
|
||||
"environment_id", m_EnvironmentId,
|
||||
"host_id", GetObjectIdentifier(host),
|
||||
|
|
@ -2583,7 +2591,7 @@ void IcingaDB::SendAcknowledgementCleared(const Checkable::Ptr& checkable, const
|
|||
/* Update checkable state as is_acknowledged may have changed. */
|
||||
UpdateState(checkable, StateUpdate::Full);
|
||||
|
||||
std::vector<String> xAdd ({
|
||||
RedisConnection::Query xAdd ({
|
||||
"XADD", "icinga:history:stream:acknowledgement", "*",
|
||||
"environment_id", m_EnvironmentId,
|
||||
"host_id", GetObjectIdentifier(host),
|
||||
|
|
@ -3335,7 +3343,7 @@ void IcingaDB::DeleteRelationship(const String& id, const String& redisKeyWithou
|
|||
|
||||
String redisKey = m_PrefixConfigObject + redisKeyWithoutPrefix;
|
||||
|
||||
std::vector<std::vector<String>> queries;
|
||||
RedisConnection::Queries queries;
|
||||
|
||||
if (hasChecksum) {
|
||||
queries.push_back({"HDEL", m_PrefixConfigCheckSum + redisKeyWithoutPrefix, id});
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ void IcingaDB::PublishStats()
|
|||
status->Set("timestamp", TimestampToMilliseconds(Utility::GetTime()));
|
||||
status->Set("icingadb_environment", m_EnvironmentId);
|
||||
|
||||
std::vector<String> query {"XADD", "icinga:stats", "MAXLEN", "1", "*"};
|
||||
RedisConnection::Query query {"XADD", "icinga:stats", "MAXLEN", "1", "*"};
|
||||
|
||||
{
|
||||
ObjectLock statusLock (status);
|
||||
|
|
|
|||
|
|
@ -113,13 +113,13 @@ private:
|
|||
std::vector<String> GetTypeDumpSignalKeys(const Type::Ptr& type);
|
||||
void InsertCheckableDependencies(const Checkable::Ptr& checkable, std::map<String, RedisConnection::Query>& hMSets,
|
||||
std::vector<Dictionary::Ptr>* runtimeUpdates, const DependencyGroup::Ptr& onlyDependencyGroup = nullptr);
|
||||
void InsertObjectDependencies(const ConfigObject::Ptr& object, const String typeName, std::map<String, std::vector<String>>& hMSets,
|
||||
void InsertObjectDependencies(const ConfigObject::Ptr& object, const String typeName, std::map<String, RedisConnection::Query>& hMSets,
|
||||
std::vector<Dictionary::Ptr>& runtimeUpdates, bool runtimeUpdate);
|
||||
void UpdateDependenciesState(const Checkable::Ptr& checkable, const DependencyGroup::Ptr& onlyDependencyGroup = nullptr,
|
||||
std::set<DependencyGroup*>* seenGroups = nullptr) const;
|
||||
void UpdateState(const Checkable::Ptr& checkable, StateUpdate mode);
|
||||
void SendConfigUpdate(const ConfigObject::Ptr& object, bool runtimeUpdate);
|
||||
void CreateConfigUpdate(const ConfigObject::Ptr& object, const String type, std::map<String, std::vector<String>>& hMSets,
|
||||
void CreateConfigUpdate(const ConfigObject::Ptr& object, const String type, std::map<String, RedisConnection::Query>& hMSets,
|
||||
std::vector<Dictionary::Ptr>& runtimeUpdates, bool runtimeUpdate);
|
||||
void SendConfigDelete(const ConfigObject::Ptr& object);
|
||||
void SendStateChange(const ConfigObject::Ptr& object, const CheckResult::Ptr& cr, StateType type);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,15 @@ namespace asio = boost::asio;
|
|||
|
||||
boost::regex RedisConnection::m_ErrAuth ("\\AERR AUTH ");
|
||||
|
||||
RedisConnection::QueryArg::operator std::string_view() const
|
||||
{
|
||||
if (auto str (std::get_if<String>(&m_Data)); str) {
|
||||
return *str;
|
||||
}
|
||||
|
||||
return std::get<std::string_view>(m_Data);
|
||||
}
|
||||
|
||||
RedisConnection::RedisConnection(const String& host, int port, const String& path, const String& username, const String& password, int db,
|
||||
bool useTls, bool insecure, const String& certPath, const String& keyPath, const String& caPath, const String& crlPath,
|
||||
const String& tlsProtocolmin, const String& cipherList, double connectTimeout, DebugInfo di, const RedisConnection::Ptr& parent)
|
||||
|
|
@ -100,10 +109,12 @@ void LogQuery(RedisConnection::Query& query, Log& msg)
|
|||
break;
|
||||
}
|
||||
|
||||
if (arg.GetLength() > 64) {
|
||||
msg << " '" << arg.SubStr(0, 61) << "...'";
|
||||
std::string_view sv (arg);
|
||||
|
||||
if (sv.length() > 64) {
|
||||
msg << " '" << sv.substr(0, 61) << "...'";
|
||||
} else {
|
||||
msg << " '" << arg << '\'';
|
||||
msg << " '" << sv << '\'';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@
|
|||
#include <queue>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace icinga
|
||||
|
|
@ -54,7 +56,39 @@ namespace icinga
|
|||
public:
|
||||
DECLARE_PTR_TYPEDEFS(RedisConnection);
|
||||
|
||||
typedef std::vector<String> Query;
|
||||
/**
|
||||
* A Redis query argument. Either owned String, borrowed std::string_view or hardcoded const char[].
|
||||
* Allows mixing these types in a single query transparently, not requiring any conversions.
|
||||
*
|
||||
* @ingroup icingadb
|
||||
*/
|
||||
class QueryArg
|
||||
{
|
||||
public:
|
||||
explicit QueryArg(std::string_view data) : m_Data(data)
|
||||
{
|
||||
}
|
||||
|
||||
QueryArg(String data): m_Data(std::move(data))
|
||||
{
|
||||
}
|
||||
|
||||
QueryArg(const char* data) : m_Data(std::string_view(data))
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator std::string_view() const;
|
||||
|
||||
std::variant<std::string_view, String>& GetData()
|
||||
{
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
private:
|
||||
std::variant<std::string_view, String> m_Data;
|
||||
};
|
||||
|
||||
typedef std::vector<QueryArg> Query;
|
||||
typedef std::vector<Query> Queries;
|
||||
typedef Value Reply;
|
||||
typedef std::vector<Reply> Replies;
|
||||
|
|
@ -665,7 +699,9 @@ void RedisConnection::WriteRESP(AsyncWriteStream& stream, const Query& query, bo
|
|||
msg << "*" << query.size() << "\r\n";
|
||||
|
||||
for (auto& arg : query) {
|
||||
msg << "$" << arg.GetLength() << "\r\n" << arg << "\r\n";
|
||||
std::string_view sv (arg);
|
||||
|
||||
msg << "$" << sv.length() << "\r\n" << sv << "\r\n";
|
||||
}
|
||||
|
||||
asio::async_write(stream, writeBuffer, yc);
|
||||
|
|
|
|||
Loading…
Reference in a new issue