1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-15 17:51:06 +00:00
dragonflydb-dragonfly/server/reply_builder.h

134 lines
3 KiB
C++

// Copyright 2021, Roman Gershman. All rights reserved.
// See LICENSE for licensing terms.
//
#include <optional>
#include <string_view>
#include "core/op_status.h"
#include "io/sync_stream_interface.h"
#include "server/common_types.h"
namespace dfly {
class BaseSerializer {
public:
explicit BaseSerializer(::io::Sink* sink);
virtual ~BaseSerializer() {
}
std::error_code ec() const {
return ec_;
}
void CloseConnection() {
if (!ec_)
ec_ = std::make_error_code(std::errc::connection_aborted);
}
// In order to reduce interrupt rate we allow coalescing responses together using
// Batch mode. It is controlled by Connection state machine because it makes sense only
// when pipelined requests are arriving.
void SetBatchMode(bool batch) {
should_batch_ = batch;
}
//! Sends a string as is without any formatting. raw should be encoded according to the protocol.
void SendDirect(std::string_view str);
void Send(const iovec* v, uint32_t len);
private:
::io::Sink* sink_;
std::error_code ec_;
std::string batch_;
bool should_batch_ = false;
};
class RespSerializer : public BaseSerializer {
public:
RespSerializer(::io::Sink* sink) : BaseSerializer(sink) {
}
//! See https://redis.io/topics/protocol
void SendSimpleString(std::string_view str);
void SendNull();
/// aka "$6\r\nfoobar\r\n"
void SendBulkString(std::string_view str);
};
class MemcacheSerializer : public BaseSerializer {
public:
explicit MemcacheSerializer(::io::Sink* sink) : BaseSerializer(sink) {
}
void SendStored();
void SendError();
};
class ReplyBuilder {
public:
ReplyBuilder(Protocol protocol, ::io::Sink* stream);
void SendStored();
void SendError(std::string_view str);
void SendError(OpStatus status);
void SendOk() {
as_resp()->SendSimpleString("OK");
}
std::error_code ec() const {
return serializer_->ec();
}
void SendMCClientError(std::string_view str);
void EndMultilineReply();
void SendSimpleRespString(std::string_view str) {
as_resp()->SendSimpleString(str);
}
void SendRespBlob(std::string_view str) {
as_resp()->SendDirect(str);
}
void SendGetReply(std::string_view key, uint32_t flags, std::string_view value);
void SendGetNotFound();
using StrOrNil = std::optional<std::string_view>;
void SendMGetResponse(const StrOrNil* arr, uint32_t count);
void SetBatchMode(bool mode) {
serializer_->SetBatchMode(mode);
}
// Resp specific.
// This one is prefixed with + and with clrf added automatically to each item..
void SendSimpleStrArr(const std::string_view* arr, uint32_t count);
void SendNull() {
as_resp()->SendNull();
}
void SendLong(long val);
void SendBulkString(std::string_view str) {
as_resp()->SendBulkString(str);
}
private:
RespSerializer* as_resp() {
return static_cast<RespSerializer*>(serializer_.get());
}
MemcacheSerializer* as_mc() {
return static_cast<MemcacheSerializer*>(serializer_.get());
}
std::unique_ptr<BaseSerializer> serializer_;
Protocol protocol_;
};
} // namespace dfly