Skip to content

Commit 80b83de

Browse files
committed
dnsdist: remove pipeline functionality from RedisClient
Signed-off-by: Ensar Sarajčić <dev@ensarsarajcic.com>
1 parent 1760ec1 commit 80b83de

6 files changed

Lines changed: 14 additions & 220 deletions

File tree

pdns/dnsdistdist/dnsdist-configuration-yaml.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ void registerRedisClientObjects([[maybe_unused]] const ::rust::Vec<RedisClientCo
20952095
{
20962096
#ifdef HAVE_REDIS
20972097
for (const auto& redisClient : redisClients) {
2098-
dnsdist::configuration::yaml::registerType<RedisClient>(std::make_shared<RedisClient>(std::string(redisClient.url), redisClient.pipeline_enabled, redisClient.pipeline_interval), redisClient.name);
2098+
dnsdist::configuration::yaml::registerType<RedisClient>(std::make_shared<RedisClient>(std::string(redisClient.url)), redisClient.name);
20992099
}
21002100
#endif
21012101
}

pdns/dnsdistdist/dnsdist-lua-bindings-redis.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,12 @@
2626
void setupLuaBindingsRedis([[maybe_unused]] LuaContext& luaCtx, [[maybe_unused]] bool client)
2727
{
2828
#ifdef HAVE_REDIS
29-
luaCtx.writeFunction("newRedisClient", [client](const std::string& url, std::optional<LuaAssociativeTable<boost::variant<bool, std::string>>> vars) {
29+
luaCtx.writeFunction("newRedisClient", [client](const std::string& url) {
3030
if (client) {
3131
return std::shared_ptr<RedisClient>(nullptr);
3232
}
3333

34-
bool pipelineEnabled{true};
35-
int pipelineInterval{10};
36-
getOptionalValue<bool>(vars, "pipelineEnabled", pipelineEnabled);
37-
getOptionalIntegerValue<int>("newRedisClient", vars, "pipelineInterval", pipelineInterval);
38-
checkAllParametersConsumed("newRedisClient", vars);
39-
40-
return std::make_shared<RedisClient>(url, pipelineEnabled, pipelineInterval);
34+
return std::make_shared<RedisClient>(url);
4135
});
4236

4337
luaCtx.registerFunction<std::string (std::shared_ptr<RedisClient>::*)(const std::string&)>("get", [](std::shared_ptr<RedisClient>& rc, const std::string& key) {

pdns/dnsdistdist/dnsdist-rust-lib/rust-post-in.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ fn get_global_configuration_from_serde(
9696
dnsdistsettings::registerKVSObjects(&config.key_value_stores);
9797
// this needs to be done before the rules so that they can refer to the NMG objects
9898
dnsdistsettings::registerNMGObjects(&config.netmask_groups);
99+
dnsdistsettings::registerRedisClientObjects(&config.redis_clients);
99100
// this needs to be done before the rules so that they can refer to the TimeIPSet objects
100101
dnsdistsettings::registerTimedIPSetObjects(&config.timed_ip_sets);
101102
// this needs to be done BEFORE the rules so that they can refer to the selectors

pdns/dnsdistdist/dnsdist-settings-definitions.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,6 @@ redis_client:
201201
- name: "url"
202202
type: "String"
203203
description: "URL of the Redis instance to connect to"
204-
- name: "pipeline_enabled"
205-
type: "bool"
206-
default: "true"
207-
description: "Whether command pipelining should be enabled for this client"
208-
- name: "pipeline_interval"
209-
type: "u32"
210-
default: "10"
211-
description: "Interval to send commands at when pipelining is enabled"
212204

213205
remote_logging:
214206
description: "Queries and/or responses remote logging settings"

pdns/dnsdistdist/redis.cc

Lines changed: 6 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ redisReply* RedisClient::executeCommand(const char* format, ...) const
8383
{
8484
va_list ap;
8585
va_start(ap, format);
86-
auto result = d_executor->executeCommand(format, ap);
86+
auto connection = d_connection.getConnection();
87+
auto result = static_cast<redisReply*>(redisvCommand(connection->get(), format, ap));
88+
if (connection->get()->err != 0) {
89+
vinfolog("Redis connection error %s", connection->get()->errstr);
90+
}
8791
va_end(ap);
8892
return result;
8993
};
@@ -96,143 +100,14 @@ redisReply* RedisClient::executeCommandArgv(std::vector<std::string> args) const
96100
argv.push_back(args[i].data());
97101
argvlen.push_back(args[i].length());
98102
}
99-
return d_executor->executeCommandArgv(args.size(), argv.data(), argvlen.data());
100-
};
101-
102-
redisReply* RedisClient::DirectExecutor::executeCommand(const char* format, va_list ap) const
103-
{
104103
auto connection = d_connection.getConnection();
105-
auto result = static_cast<redisReply*>(redisvCommand(connection->get(), format, ap));
104+
auto result = static_cast<redisReply*>(redisCommandArgv(connection->get(), args.size(), argv.data(), argvlen.data()));
106105
if (connection->get()->err != 0) {
107106
vinfolog("Redis connection error %s", connection->get()->errstr);
108107
}
109108
return result;
110-
}
111-
112-
redisReply* RedisClient::DirectExecutor::executeCommandArgv(int argc, const char** argv, const size_t* argvlen) const
113-
{
114-
auto connection = d_connection.getConnection();
115-
auto result = static_cast<redisReply*>(redisCommandArgv(connection->get(), argc, argv, argvlen));
116-
if (connection->get()->err != 0) {
117-
vinfolog("Redis connection error %s", connection->get()->errstr);
118-
}
119-
return result;
120-
}
121-
122-
RedisClient::PipelineExecutor::PipelineExecutor(const std::string& url, uint32_t pipelineInterval) :
123-
d_connection(url), d_interval(pipelineInterval)
124-
{
125-
auto [sender, receiver] = pdns::channel::createObjectQueue<PipelineCommand>();
126-
d_pipelineSender = std::move(sender);
127-
d_pipelineReceiver = std::move(receiver);
128-
129-
d_thread = std::thread(&RedisClient::PipelineExecutor::maintenanceThread, this);
130-
}
131-
132-
redisReply* RedisClient::PipelineExecutor::executeCommandArgv(int argc, const char** argv, const size_t* argvlen) const
133-
{
134-
char* command;
135-
auto len = redisFormatCommandArgv(&command, argc, argv, argvlen);
136-
if (len < 0) {
137-
// TODO: handle formatting errors?
138-
vinfolog("Redis command formatting error");
139-
return nullptr;
140-
}
141-
142-
return pipelineCommand(command, len);
143-
}
144-
145-
redisReply* RedisClient::PipelineExecutor::executeCommand(const char* format, va_list ap) const
146-
{
147-
char* command;
148-
auto len = redisvFormatCommand(&command, format, ap);
149-
if (len < 0) {
150-
// TODO: handle formatting errors?
151-
vinfolog("Redis command formatting error");
152-
return nullptr;
153-
}
154-
155-
return pipelineCommand(command, len);
156-
}
157-
158-
redisReply* RedisClient::PipelineExecutor::pipelineCommand(const char* command, size_t len) const
159-
{
160-
std::mutex mtx;
161-
std::condition_variable cv;
162-
std::unique_lock<std::mutex> lock(mtx);
163-
std::shared_ptr<redisReply*> result = std::make_shared<redisReply*>(nullptr);
164-
PipelineCommand::callback_t callback = [result, &cv](redisReply* reply) mutable {
165-
*result = reply;
166-
cv.notify_one();
167-
};
168-
d_pipelineSender.send(std::make_unique<PipelineCommand>(PipelineCommand{
169-
command,
170-
len,
171-
callback}));
172-
cv.wait(lock);
173-
return *result;
174-
}
175-
176-
void RedisClient::PipelineExecutor::maintenanceThread()
177-
{
178-
setThreadName("dnsdist/redis");
179-
180-
for (;;) {
181-
if (d_exiting) {
182-
break;
183-
}
184-
185-
bool connected = true;
186-
if (d_connection.needsReconnect()) {
187-
connected = d_connection.reconnect();
188-
}
189-
190-
if (connected) {
191-
auto connection = d_connection.getConnection();
192-
std::list<PipelineCommand::callback_t> callbacks;
193-
while (auto command = d_pipelineReceiver.receive()) {
194-
if (redisAppendFormattedCommand(connection->get(), command->get()->command, command->get()->length) == REDIS_OK) {
195-
callbacks.push_back(command->get()->callback);
196-
}
197-
else {
198-
if (connection->get()->err != 0) {
199-
vinfolog("Redis connection error %s", connection->get()->errstr);
200-
}
201-
else {
202-
vinfolog("Unknown redis connection error");
203-
}
204-
command->get()->callback(nullptr);
205-
}
206-
}
207-
208-
for (auto callback : callbacks) {
209-
void* reply;
210-
if (redisGetReply(connection->get(), &reply) == REDIS_OK) {
211-
callback(static_cast<redisReply*>(reply));
212-
}
213-
else {
214-
if (connection->get()->err != 0) {
215-
vinfolog("Redis connection error %s", connection->get()->errstr);
216-
}
217-
else {
218-
vinfolog("Unknown redis connection error");
219-
}
220-
callback(nullptr);
221-
}
222-
}
223-
}
224-
225-
std::this_thread::sleep_for(std::chrono::milliseconds(d_interval));
226-
}
227109
};
228110

229-
RedisClient::PipelineExecutor::~PipelineExecutor()
230-
{
231-
d_exiting = true;
232-
233-
d_thread.join();
234-
}
235-
236111
bool RedisKVClient::getValue(const std::string& key, std::string& value)
237112
{
238113
auto reply = d_lookupAction->getValue(*d_client, key);

pdns/dnsdistdist/redis.hh

Lines changed: 4 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -316,22 +316,15 @@ private:
316316
class RedisClient
317317
{
318318
public:
319-
RedisClient(const std::string& url, bool enablePipeline = true, uint32_t pipelineInterval = 10)
320-
{
321-
if (enablePipeline) {
322-
d_executor = std::make_unique<PipelineExecutor>(url, pipelineInterval);
323-
}
324-
else {
325-
d_executor = std::make_unique<DirectExecutor>(url);
326-
}
327-
}
319+
RedisClient(const std::string& url) :
320+
d_connection(url) {}
328321

329322
redisReply* executeCommand(const char* format, ...) const;
330323
redisReply* executeCommandArgv(std::vector<std::string> args) const;
331324

332325
const YaHTTP::URL& getUrl() const
333326
{
334-
return d_executor->getUrl();
327+
return d_connection.getUrl();
335328
}
336329

337330
private:
@@ -361,68 +354,7 @@ private:
361354
YaHTTP::URL d_url;
362355
};
363356

364-
class Executor
365-
{
366-
public:
367-
virtual ~Executor() = default;
368-
virtual redisReply* executeCommand(const char* format, va_list ap) const = 0;
369-
virtual redisReply* executeCommandArgv(int argc, const char** argv, const size_t* argvlen) const = 0;
370-
virtual const YaHTTP::URL& getUrl() const = 0;
371-
};
372-
373-
class DirectExecutor : public Executor
374-
{
375-
public:
376-
DirectExecutor(const std::string& url) :
377-
d_connection(url)
378-
{
379-
}
380-
redisReply* executeCommand(const char* format, va_list ap) const override;
381-
redisReply* executeCommandArgv(int argc, const char** argv, const size_t* argvlen) const override;
382-
383-
const YaHTTP::URL& getUrl() const override
384-
{
385-
return d_connection.getUrl();
386-
}
387-
388-
private:
389-
RedisConnection d_connection;
390-
};
391-
392-
class PipelineExecutor : public Executor
393-
{
394-
public:
395-
PipelineExecutor(const std::string& url, uint32_t pipelineInterval);
396-
~PipelineExecutor();
397-
redisReply* executeCommand(const char* format, va_list ap) const override;
398-
redisReply* executeCommandArgv(int argc, const char** argv, const size_t* argvlen) const override;
399-
400-
const YaHTTP::URL& getUrl() const override
401-
{
402-
return d_connection.getUrl();
403-
}
404-
405-
private:
406-
void maintenanceThread();
407-
redisReply* pipelineCommand(const char* command, size_t len) const;
408-
409-
struct PipelineCommand
410-
{
411-
typedef std::function<void(redisReply*)> callback_t;
412-
const char* command;
413-
size_t length;
414-
callback_t callback;
415-
};
416-
RedisConnection d_connection;
417-
uint32_t d_interval;
418-
pdns::channel::Sender<PipelineCommand> d_pipelineSender;
419-
pdns::channel::Receiver<PipelineCommand> d_pipelineReceiver;
420-
421-
std::atomic<bool> d_exiting{false};
422-
std::thread d_thread;
423-
};
424-
425-
std::unique_ptr<Executor> d_executor;
357+
RedisConnection d_connection;
426358
};
427359

428360
class RedisKVClientInterface

0 commit comments

Comments
 (0)